Skip to content
Snippets Groups Projects
Commit dc9b4b22 authored by Zhengping Jiang's avatar Zhengping Jiang
Browse files

Floss: Add restart bluetooth and apply ll privacy status

Add restart bluetooth to state machine and restart any enabled adapters
when ll privacy status is changed.

Restarting ProcessState can only transit from On. It will be no op for
other SM states. For example, a disabled adapter will stay disabled
after calling restart_bluetooth.

Bug: 242100561
Tag: #floss
Test: manual run dbus command to enable/disable ll privacy
Test: mma -j32

Change-Id: Ib1cba068aea9da47c1cbe7ce62e524e819f9de8f
parent 8a1048e5
No related branches found
No related tags found
No related merge requests found
......@@ -60,6 +60,14 @@ impl BluetoothManager {
pub(crate) fn callback_disconnected(&mut self, id: u32) {
self.callbacks.remove(&id);
}
pub(crate) fn restart_available_adapters(&mut self) {
self.get_available_adapters()
.into_iter()
.filter(|adapter| adapter.enabled)
.map(|adapter| VirtualHciIndex(adapter.hci_interface))
.for_each(|virt_hci| self.proxy.restart_bluetooth(virt_hci));
}
}
impl IBluetoothManager for BluetoothManager {
......@@ -182,10 +190,13 @@ impl IBluetoothExperimental for BluetoothManager {
return;
}
info!("Set floss ll privacy to {}", enabled);
if let Err(e) = config_util::write_floss_ll_privacy_enabled(enabled) {
error!("Failed to write ll privacy status: {}", e);
return;
}
self.restart_available_adapters();
}
fn set_devcoredump(&mut self, enabled: bool) -> bool {
......
......@@ -38,6 +38,7 @@ pub enum ProcessState {
TurningOn = 1, // We are not notified that the Bluetooth is running
On = 2, // Bluetooth is running
TurningOff = 3, // We are not notified that the Bluetooth is stopped
Restarting = 4, // Pending restart and not notified that the Bluetooth is stopped
}
/// Check whether adapter is enabled by checking internal state.
......@@ -90,6 +91,7 @@ impl Display for RealHciIndex {
pub enum AdapterStateActions {
StartBluetooth(VirtualHciIndex),
StopBluetooth(VirtualHciIndex),
RestartBluetooth(VirtualHciIndex),
BluetoothStarted(i32, RealHciIndex), // PID and HCI
BluetoothStopped(RealHciIndex),
HciDevicePresence(DevPath, RealHciIndex, bool),
......@@ -186,6 +188,15 @@ impl StateMachineProxy {
});
}
pub fn restart_bluetooth(&self, hci: VirtualHciIndex) {
let tx = self.tx.clone();
tokio::spawn(async move {
let _ = tx
.send(Message::AdapterStateChange(AdapterStateActions::RestartBluetooth(hci)))
.await;
});
}
/// Read state for an hci device.
pub fn get_state<T, F>(&self, hci: VirtualHciIndex, call: F) -> Option<T>
where
......@@ -654,6 +665,14 @@ pub async fn mainloop(
let action = context.state_machine.action_stop_bluetooth(hci);
cmd_timeout.lock().unwrap().handle_timeout_action(hci, action);
}
AdapterStateActions::RestartBluetooth(i) => {
hci = *i;
prev_state = context.state_machine.get_process_state(hci);
next_state = ProcessState::Restarting;
let action = context.state_machine.action_restart_bluetooth(hci);
cmd_timeout.lock().unwrap().handle_timeout_action(hci, action);
}
AdapterStateActions::BluetoothStarted(pid, real_hci) => {
hci = match context.state_machine.get_virtual_id_by_real_id(*real_hci) {
Some(v) => v,
......@@ -1310,6 +1329,32 @@ impl StateMachineInternal {
}
}
/// Returns true if we are restarting bluetooth process
pub fn action_restart_bluetooth(&mut self, hci: VirtualHciIndex) -> CommandTimeoutAction {
if !self.is_known(hci) {
warn!("Attempting to restart unknown hci{}", hci);
return CommandTimeoutAction::DoNothing;
}
let state = self.get_process_state(hci);
let present = self.get_state(hci, move |a: &AdapterState| Some(a.present)).unwrap_or(false);
let floss_enabled = self.get_floss_enabled();
match state {
ProcessState::On if present && floss_enabled => {
self.modify_state(hci, |s: &mut AdapterState| s.state = ProcessState::Restarting);
self.process_manager
.stop(hci.to_string(), self.get_real_hci_by_virtual_id(hci).to_string());
CommandTimeoutAction::ResetTimer
}
ProcessState::TurningOn => {
debug!("hci{} is already starting.", hci);
CommandTimeoutAction::DoNothing
}
_ => CommandTimeoutAction::DoNothing,
}
}
/// Handles a bluetooth started event. Always returns true even with unknown interfaces.
pub fn action_on_bluetooth_started(
&mut self,
......@@ -1345,6 +1390,13 @@ impl StateMachineInternal {
self.modify_state(hci, |s: &mut AdapterState| s.state = ProcessState::Off);
CommandTimeoutAction::CancelTimer
}
ProcessState::Restarting => {
debug!("hci{} restarting", hci.to_i32());
self.modify_state(hci, |s: &mut AdapterState| s.state = ProcessState::TurningOn);
self.process_manager
.start(hci.to_string(), self.get_real_hci_by_virtual_id(hci).to_string());
CommandTimeoutAction::ResetTimer
}
// Running bluetooth stopped unexpectedly.
ProcessState::On if floss_enabled && config_enabled => {
let restart_count =
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment