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