1 /*
2 * Copyright 2021 HIMSA II K/S - www.himsa.com.
3 * Represented by EHIMA - www.ehima.com
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /* Volume Control Interface */
19
20 #include <hardware/bluetooth.h>
21 #include <hardware/bt_vc.h>
22
23 #include <base/bind.h>
24 #include <base/location.h>
25 #include <base/logging.h>
26
27 #include "bta_vc_api.h"
28 #include "btif_common.h"
29 #include "stack/include/btu.h"
30
31 using base::Bind;
32 using base::Unretained;
33 using bluetooth::vc::ConnectionState;
34 using bluetooth::vc::VolumeControlCallbacks;
35 using bluetooth::vc::VolumeControlInterface;
36
37 namespace {
38 std::unique_ptr<VolumeControlInterface> vc_instance;
39
40 class VolumeControlInterfaceImpl : public VolumeControlInterface,
41 public VolumeControlCallbacks {
42 ~VolumeControlInterfaceImpl() override = default;
43
Init(VolumeControlCallbacks * callbacks)44 void Init(VolumeControlCallbacks* callbacks) override {
45 DVLOG(2) << __func__;
46 this->callbacks_ = callbacks;
47 do_in_main_thread(FROM_HERE, Bind(&VolumeControl::Initialize, this));
48 }
49
OnConnectionState(ConnectionState state,const RawAddress & address)50 void OnConnectionState(ConnectionState state,
51 const RawAddress& address) override {
52 DVLOG(2) << __func__ << " address: " << address;
53 do_in_jni_thread(FROM_HERE, Bind(&VolumeControlCallbacks::OnConnectionState,
54 Unretained(callbacks_), state, address));
55 }
56
OnVolumeStateChanged(const RawAddress & address,uint8_t volume,bool mute)57 void OnVolumeStateChanged(const RawAddress& address, uint8_t volume,
58 bool mute) override {
59 DVLOG(2) << __func__ << " address: " << address << "volume: " << volume
60 << "mute: " << mute;
61 do_in_jni_thread(FROM_HERE,
62 Bind(&VolumeControlCallbacks::OnVolumeStateChanged,
63 Unretained(callbacks_), address, volume, mute));
64 }
65
OnGroupVolumeStateChanged(int group_id,uint8_t volume,bool mute)66 void OnGroupVolumeStateChanged(int group_id, uint8_t volume,
67 bool mute) override {
68 DVLOG(2) << __func__ << "group_id: " << group_id << "volume: " << volume
69 << "mute: " << mute;
70 do_in_jni_thread(FROM_HERE,
71 Bind(&VolumeControlCallbacks::OnGroupVolumeStateChanged,
72 Unretained(callbacks_), group_id, volume, mute));
73 }
74
Connect(const RawAddress & address)75 void Connect(const RawAddress& address) override {
76 DVLOG(2) << __func__ << " address: " << address;
77 do_in_main_thread(FROM_HERE,
78 Bind(&VolumeControl::Connect,
79 Unretained(VolumeControl::Get()), address));
80 }
81
Disconnect(const RawAddress & address)82 void Disconnect(const RawAddress& address) override {
83 DVLOG(2) << __func__ << " address: " << address;
84 do_in_main_thread(FROM_HERE,
85 Bind(&VolumeControl::Disconnect,
86 Unretained(VolumeControl::Get()), address));
87 }
88
SetVolume(std::variant<RawAddress,int> addr_or_group_id,uint8_t volume)89 void SetVolume(std::variant<RawAddress, int> addr_or_group_id,
90 uint8_t volume) override {
91 DVLOG(2) << __func__ << " volume: " << volume;
92 do_in_main_thread(FROM_HERE, Bind(&VolumeControl::SetVolume,
93 Unretained(VolumeControl::Get()),
94 std::move(addr_or_group_id), volume));
95 }
96
RemoveDevice(const RawAddress & address)97 void RemoveDevice(const RawAddress& address) override {
98 DVLOG(2) << __func__ << " address: " << address;
99
100 /* RemoveDevice can be called on devices that don't have HA enabled */
101 if (VolumeControl::IsVolumeControlRunning()) {
102 do_in_main_thread(FROM_HERE,
103 Bind(&VolumeControl::Disconnect,
104 Unretained(VolumeControl::Get()), address));
105 }
106
107 /* Placeholder: Remove things from storage here */
108 }
109
Cleanup(void)110 void Cleanup(void) override {
111 DVLOG(2) << __func__;
112 do_in_main_thread(FROM_HERE, Bind(&VolumeControl::CleanUp));
113 }
114
115 private:
116 VolumeControlCallbacks* callbacks_;
117 };
118
119 } /* namespace */
120
btif_volume_control_get_interface(void)121 VolumeControlInterface* btif_volume_control_get_interface(void) {
122 if (!vc_instance) vc_instance.reset(new VolumeControlInterfaceImpl());
123
124 return vc_instance.get();
125 }
126