1 use crate::btif::{BluetoothInterface, BtStatus, RawAddress, SupportedProfiles, ToggleableProfile};
2 use crate::topstack::get_dispatchers;
3 
4 use std::sync::{Arc, Mutex};
5 use topshim_macros::{cb_variant, profile_enabled_or};
6 
7 use crate::bindings::root as bindings;
8 use crate::ccall;
9 use crate::utils::LTCheckedPtrMut;
10 
11 use log::warn;
12 
13 #[derive(Debug, Default)]
14 pub struct PlayerMetadata {
15     pub title: String,
16     pub artist: String,
17     pub album: String,
18     pub length_us: i64,
19 }
20 
21 #[cxx::bridge(namespace = bluetooth::topshim::rust)]
22 pub mod ffi {
23     unsafe extern "C++" {
24         include!("types/raw_address.h");
25         #[namespace = ""]
26         type RawAddress = crate::btif::RawAddress;
27     }
28 
29     unsafe extern "C++" {
30         include!("btav/btav_shim.h");
31         include!("btav_sink/btav_sink_shim.h");
32 
33         type AvrcpIntf;
34 
GetAvrcpProfile(btif: *const u8) -> UniquePtr<AvrcpIntf>35         unsafe fn GetAvrcpProfile(btif: *const u8) -> UniquePtr<AvrcpIntf>;
36 
init(self: Pin<&mut AvrcpIntf>)37         fn init(self: Pin<&mut AvrcpIntf>);
cleanup(self: Pin<&mut AvrcpIntf>)38         fn cleanup(self: Pin<&mut AvrcpIntf>);
connect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u3239         fn connect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u32;
disconnect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u3240         fn disconnect(self: Pin<&mut AvrcpIntf>, bt_addr: RawAddress) -> u32;
set_volume(self: Pin<&mut AvrcpIntf>, volume: i8)41         fn set_volume(self: Pin<&mut AvrcpIntf>, volume: i8);
set_playback_status(self: Pin<&mut AvrcpIntf>, status: &String)42         fn set_playback_status(self: Pin<&mut AvrcpIntf>, status: &String);
set_position(self: Pin<&mut AvrcpIntf>, position_us: i64)43         fn set_position(self: Pin<&mut AvrcpIntf>, position_us: i64);
set_metadata( self: Pin<&mut AvrcpIntf>, title: &String, artist: &String, album: &String, length_us: i64, )44         fn set_metadata(
45             self: Pin<&mut AvrcpIntf>,
46             title: &String,
47             artist: &String,
48             album: &String,
49             length_us: i64,
50         );
add_player(self: Pin<&mut AvrcpIntf>, name: &String, browsing_supported: bool) -> u1651         fn add_player(self: Pin<&mut AvrcpIntf>, name: &String, browsing_supported: bool) -> u16;
52 
53     }
54     extern "Rust" {
avrcp_device_connected(addr: RawAddress, absolute_volume_enabled: bool)55         fn avrcp_device_connected(addr: RawAddress, absolute_volume_enabled: bool);
avrcp_device_disconnected(addr: RawAddress)56         fn avrcp_device_disconnected(addr: RawAddress);
avrcp_absolute_volume_update(volume: u8)57         fn avrcp_absolute_volume_update(volume: u8);
avrcp_send_key_event(key: u8, state: u8)58         fn avrcp_send_key_event(key: u8, state: u8);
avrcp_set_active_device(addr: RawAddress)59         fn avrcp_set_active_device(addr: RawAddress);
60     }
61 }
62 
63 #[derive(Debug)]
64 pub enum AvrcpCallbacks {
65     /// Emitted when avrcp completes connection.
66     /// Params: Device address, Absolute Volume Enabled
67     AvrcpDeviceConnected(RawAddress, bool),
68     /// Emitted when avrcp device disconnected.
69     /// Params: Device address
70     AvrcpDeviceDisconnected(RawAddress),
71     /// Emitted when the absolute volume of a connected AVRCP device changed
72     /// Params: Volume
73     AvrcpAbsoluteVolumeUpdate(u8),
74     /// Emitted when received a key event from a connected AVRCP device
75     /// Params: Key, Value
76     AvrcpSendKeyEvent(u8, u8),
77     /// Emitted when received request from AVRCP interface to set a device to active
78     /// Params: Device address
79     AvrcpSetActiveDevice(RawAddress),
80 }
81 
82 pub struct AvrcpCallbacksDispatcher {
83     pub dispatch: Box<dyn Fn(AvrcpCallbacks) + Send>,
84 }
85 
86 type AvrcpCb = Arc<Mutex<AvrcpCallbacksDispatcher>>;
87 
88 cb_variant!(
89     AvrcpCb,
90     avrcp_device_connected -> AvrcpCallbacks::AvrcpDeviceConnected,
91     RawAddress, bool);
92 
93 cb_variant!(
94     AvrcpCb,
95     avrcp_device_disconnected -> AvrcpCallbacks::AvrcpDeviceDisconnected,
96     RawAddress);
97 
98 cb_variant!(
99     AvrcpCb,
100     avrcp_absolute_volume_update -> AvrcpCallbacks::AvrcpAbsoluteVolumeUpdate,
101     u8, {}
102 );
103 
104 cb_variant!(
105     AvrcpCb,
106     avrcp_send_key_event -> AvrcpCallbacks::AvrcpSendKeyEvent,
107     u8, u8, {}
108 );
109 
110 cb_variant!(
111     AvrcpCb,
112     avrcp_set_active_device -> AvrcpCallbacks::AvrcpSetActiveDevice,
113     RawAddress);
114 
115 pub struct Avrcp {
116     internal: cxx::UniquePtr<ffi::AvrcpIntf>,
117     _is_init: bool,
118     _is_enabled: bool,
119 }
120 
121 // For *const u8 opaque btif
122 unsafe impl Send for Avrcp {}
123 
124 impl ToggleableProfile for Avrcp {
is_enabled(&self) -> bool125     fn is_enabled(&self) -> bool {
126         self._is_enabled
127     }
128 
enable(&mut self) -> bool129     fn enable(&mut self) -> bool {
130         self.internal.pin_mut().init();
131         self._is_enabled = true;
132         true
133     }
134 
135     #[profile_enabled_or(false)]
disable(&mut self) -> bool136     fn disable(&mut self) -> bool {
137         self.internal.pin_mut().cleanup();
138         self._is_enabled = false;
139         true
140     }
141 }
142 
143 impl Avrcp {
new(intf: &BluetoothInterface) -> Avrcp144     pub fn new(intf: &BluetoothInterface) -> Avrcp {
145         let avrcpif: cxx::UniquePtr<ffi::AvrcpIntf>;
146         unsafe {
147             avrcpif = ffi::GetAvrcpProfile(intf.as_raw_ptr());
148         }
149 
150         Avrcp { internal: avrcpif, _is_init: false, _is_enabled: false }
151     }
152 
is_initialized(&self) -> bool153     pub fn is_initialized(&self) -> bool {
154         self._is_init
155     }
156 
initialize(&mut self, callbacks: AvrcpCallbacksDispatcher) -> bool157     pub fn initialize(&mut self, callbacks: AvrcpCallbacksDispatcher) -> bool {
158         if get_dispatchers().lock().unwrap().set::<AvrcpCb>(Arc::new(Mutex::new(callbacks))) {
159             panic!("Tried to set dispatcher for Avrcp callbacks while it already exists");
160         }
161         self._is_init = true;
162         true
163     }
164 
165     #[profile_enabled_or(BtStatus::NotReady)]
connect(&mut self, addr: RawAddress) -> BtStatus166     pub fn connect(&mut self, addr: RawAddress) -> BtStatus {
167         BtStatus::from(self.internal.pin_mut().connect(addr.into()))
168     }
169 
170     #[profile_enabled_or(BtStatus::NotReady)]
disconnect(&mut self, addr: RawAddress) -> BtStatus171     pub fn disconnect(&mut self, addr: RawAddress) -> BtStatus {
172         BtStatus::from(self.internal.pin_mut().disconnect(addr.into()))
173     }
174 
175     #[profile_enabled_or]
set_volume(&mut self, volume: i8)176     pub fn set_volume(&mut self, volume: i8) {
177         self.internal.pin_mut().set_volume(volume);
178     }
179 
180     #[profile_enabled_or(false)]
cleanup(&mut self) -> bool181     pub fn cleanup(&mut self) -> bool {
182         self.internal.pin_mut().cleanup();
183         true
184     }
185 
186     #[profile_enabled_or]
set_playback_status(&mut self, status: &String)187     pub fn set_playback_status(&mut self, status: &String) {
188         self.internal.pin_mut().set_playback_status(status);
189     }
190 
191     #[profile_enabled_or]
set_position(&mut self, position_us: i64)192     pub fn set_position(&mut self, position_us: i64) {
193         self.internal.pin_mut().set_position(position_us);
194     }
195 
196     #[profile_enabled_or]
set_metadata(&mut self, metadata: &PlayerMetadata)197     pub fn set_metadata(&mut self, metadata: &PlayerMetadata) {
198         self.internal.pin_mut().set_metadata(
199             &metadata.title,
200             &metadata.artist,
201             &metadata.album,
202             metadata.length_us,
203         );
204     }
205 
206     #[profile_enabled_or]
add_player(&mut self, name: &String, browsing_supported: bool)207     pub fn add_player(&mut self, name: &String, browsing_supported: bool) {
208         self.internal.pin_mut().add_player(name, browsing_supported);
209     }
210 }
211 
212 struct RawAvrcpCtrlWrapper {
213     raw: *const bindings::btrc_ctrl_interface_t,
214 }
215 
216 // Pointers unsafe due to ownership but this is a static pointer so Send is ok.
217 unsafe impl Send for RawAvrcpCtrlWrapper {}
218 
219 pub struct AvrcpCtrl {
220     internal: RawAvrcpCtrlWrapper,
221     callbacks: Option<Box<bindings::btrc_ctrl_callbacks_t>>,
222 }
223 
224 cb_variant!(AvrcpCtCb, avrcp_connection_state_cb -> AvrcpCtrlCallbacks::ConnectionState,
225 bool, bool, *const RawAddress, {
226     let _2 = unsafe { *_2 };
227 });
228 
229 cb_variant!(AvrcpCtCb, avrcp_getrcfeatures_cb -> AvrcpCtrlCallbacks::GetRCFeatures,
230 *const RawAddress, i32, {
231     let _0 = unsafe { *_0 };
232 });
233 
234 cb_variant!(AvrcpCtCb, avrcp_get_cover_art_psm_cb -> AvrcpCtrlCallbacks::GetCoverArtPsm,
235 *const RawAddress, u16, {
236     let _0 = unsafe { *_0 };
237 });
238 
239 cb_variant!(AvrcpCtCb, avrcp_passthrough_rsp_cb -> AvrcpCtrlCallbacks::PassthroughRsp,
240 *const RawAddress, i32, i32, {
241     let _0 = unsafe { *_0 };
242 });
243 
244 #[derive(Debug)]
245 pub enum AvrcpCtrlCallbacks {
246     PassthroughRsp(RawAddress, i32, i32),
247     ConnectionState(bool, bool, RawAddress),
248     GetRCFeatures(RawAddress, i32),
249     GetCoverArtPsm(RawAddress, u16),
250 }
251 
252 pub struct AvrcpCtrlCallbacksDispatcher {
253     pub dispatch: Box<dyn Fn(AvrcpCtrlCallbacks) + Send>,
254 }
255 
256 type AvrcpCtCb = Arc<Mutex<AvrcpCtrlCallbacksDispatcher>>;
257 
258 impl AvrcpCtrl {
new(intf: &BluetoothInterface) -> AvrcpCtrl259     pub fn new(intf: &BluetoothInterface) -> AvrcpCtrl {
260         let r = intf.get_profile_interface(SupportedProfiles::AvrcpCtrl);
261         AvrcpCtrl {
262             internal: RawAvrcpCtrlWrapper { raw: r as *const bindings::btrc_ctrl_interface_t },
263             callbacks: None,
264         }
265     }
266 
initialize(&mut self, callbacks: AvrcpCtrlCallbacksDispatcher) -> bool267     pub fn initialize(&mut self, callbacks: AvrcpCtrlCallbacksDispatcher) -> bool {
268         // Register dispatcher
269         if get_dispatchers().lock().unwrap().set::<AvrcpCtCb>(Arc::new(Mutex::new(callbacks))) {
270             panic!("Tried to set dispatcher for AvrcpCt Callbacks but it already existed");
271         }
272 
273         let callbacks = Box::new(bindings::btrc_ctrl_callbacks_t {
274             size: 21 * 8,
275             passthrough_rsp_cb: Some(avrcp_passthrough_rsp_cb),
276             groupnavigation_rsp_cb: None,
277             connection_state_cb: Some(avrcp_connection_state_cb),
278             getrcfeatures_cb: Some(avrcp_getrcfeatures_cb),
279             setplayerappsetting_rsp_cb: None,
280             playerapplicationsetting_cb: None,
281             playerapplicationsetting_changed_cb: None,
282             setabsvol_cmd_cb: None,
283             registernotification_absvol_cb: None,
284             track_changed_cb: None,
285             play_position_changed_cb: None,
286             play_status_changed_cb: None,
287             get_folder_items_cb: None,
288             change_folder_path_cb: None,
289             set_browsed_player_cb: None,
290             set_addressed_player_cb: None,
291             addressed_player_changed_cb: None,
292             now_playing_contents_changed_cb: None,
293             available_player_changed_cb: None,
294             get_cover_art_psm_cb: Some(avrcp_get_cover_art_psm_cb),
295         });
296 
297         self.callbacks = Some(callbacks);
298 
299         let cb_ptr = LTCheckedPtrMut::from(self.callbacks.as_mut().unwrap());
300 
301         ccall!(self, init, cb_ptr.into());
302 
303         true
304     }
305 
send_pass_through_cmd( &mut self, addr: RawAddress, key_code: u8, key_state: u8, ) -> BtStatus306     pub fn send_pass_through_cmd(
307         &mut self,
308         addr: RawAddress,
309         key_code: u8,
310         key_state: u8,
311     ) -> BtStatus {
312         ccall!(self, send_pass_through_cmd, &addr, key_code.into(), key_state.into()).into()
313     }
314 }
315