From 22b05a5e0938ac6575993dd89b512cd980047c4d Mon Sep 17 00:00:00 2001
From: Hansong Zhang <hsz@google.com>
Date: Fri, 27 Aug 2021 16:32:19 -0700
Subject: [PATCH] Floss: Initialize media after stack enabled

AVRCP depends on main message loop.  We need to synchronize the startup
sequence.

Test: run btadapterd
Tag: #floss
Bug: 195398850
Change-Id: Ibdaf0bbd7dedd54504d752e42a67f800cc2114f6
---
 system/gd/rust/linux/service/src/main.rs          | 11 +++++++----
 system/gd/rust/linux/stack/src/bluetooth.rs       | 13 ++++++++++++-
 system/gd/rust/linux/stack/src/bluetooth_media.rs |  3 +++
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/system/gd/rust/linux/service/src/main.rs b/system/gd/rust/linux/service/src/main.rs
index bc881c9ee8b..562bf938b99 100644
--- a/system/gd/rust/linux/service/src/main.rs
+++ b/system/gd/rust/linux/service/src/main.rs
@@ -15,7 +15,7 @@ use futures::future;
 use btstack::bluetooth::get_bt_dispatcher;
 use btstack::bluetooth::{Bluetooth, IBluetooth};
 use btstack::bluetooth_gatt::BluetoothGatt;
-use btstack::bluetooth_media::{BluetoothMedia, IBluetoothMedia};
+use btstack::bluetooth_media::BluetoothMedia;
 use btstack::Stack;
 
 use std::error::Error;
@@ -52,10 +52,14 @@ fn main() -> Result<(), Box<dyn Error>> {
     let (tx, rx) = Stack::create_channel();
 
     let intf = Arc::new(Mutex::new(get_btinterface().unwrap()));
-    let bluetooth = Arc::new(Mutex::new(Box::new(Bluetooth::new(tx.clone(), intf.clone()))));
     let bluetooth_gatt = Arc::new(Mutex::new(Box::new(BluetoothGatt::new(intf.clone()))));
     let bluetooth_media =
         Arc::new(Mutex::new(Box::new(BluetoothMedia::new(tx.clone(), intf.clone()))));
+    let bluetooth = Arc::new(Mutex::new(Box::new(Bluetooth::new(
+        tx.clone(),
+        intf.clone(),
+        bluetooth_media.clone(),
+    ))));
 
     // Args don't include arg[0] which is the binary name
     let all_args = std::env::args().collect::<Vec<String>>();
@@ -72,7 +76,6 @@ fn main() -> Result<(), Box<dyn Error>> {
         bluetooth.enable();
 
         bluetooth_gatt.lock().unwrap().init_profiles(tx.clone());
-        bluetooth_media.lock().unwrap().initialize();
     }
 
     topstack::get_runtime().block_on(async {
@@ -115,7 +118,7 @@ fn main() -> Result<(), Box<dyn Error>> {
             make_object_name(adapter_index, "adapter"),
             conn.clone(),
             &mut cr,
-            bluetooth,
+            bluetooth.clone(),
             disconnect_watcher.clone(),
         );
         // Register D-Bus method handlers of IBluetoothGatt.
diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs
index 9f9c5906d44..6c538c649cd 100644
--- a/system/gd/rust/linux/stack/src/bluetooth.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth.rs
@@ -16,6 +16,7 @@ use std::sync::Mutex;
 
 use tokio::sync::mpsc::Sender;
 
+use crate::bluetooth_media::{BluetoothMedia, IBluetoothMedia};
 use crate::{Message, RPCProxy};
 
 /// Defines the adapter API.
@@ -113,11 +114,16 @@ pub struct Bluetooth {
     tx: Sender<Message>,
     local_address: Option<RawAddress>,
     hh: Option<HidHost>,
+    bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
 }
 
 impl Bluetooth {
     /// Constructs the IBluetooth implementation.
-    pub fn new(tx: Sender<Message>, intf: Arc<Mutex<BluetoothInterface>>) -> Bluetooth {
+    pub fn new(
+        tx: Sender<Message>,
+        intf: Arc<Mutex<BluetoothInterface>>,
+        bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
+    ) -> Bluetooth {
         Bluetooth {
             tx,
             intf,
@@ -126,6 +132,7 @@ impl Bluetooth {
             callbacks_last_id: 0,
             local_address: None,
             hh: None,
+            bluetooth_media,
         }
     }
 
@@ -205,6 +212,10 @@ pub fn get_bt_dispatcher(tx: Sender<Message>) -> BaseCallbacksDispatcher {
 impl BtifBluetoothCallbacks for Bluetooth {
     fn adapter_state_changed(&mut self, state: BtState) {
         self.state = state;
+
+        if self.state == BtState::On {
+            self.bluetooth_media.lock().unwrap().initialize();
+        }
     }
 
     #[allow(unused_variables)]
diff --git a/system/gd/rust/linux/stack/src/bluetooth_media.rs b/system/gd/rust/linux/stack/src/bluetooth_media.rs
index 9244ea2e8ad..d2b13189843 100644
--- a/system/gd/rust/linux/stack/src/bluetooth_media.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth_media.rs
@@ -189,6 +189,9 @@ impl IBluetoothMedia for BluetoothMedia {
     }
 
     fn initialize(&mut self) -> bool {
+        if self.initialized {
+            return false;
+        }
         self.initialized = true;
 
         // TEST A2dp
-- 
GitLab