Loading system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs +22 −2 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,11 @@ impl ISuspendCallback for SuspendCallback { { { let context = self.context.lock().unwrap(); let context = self.context.lock().unwrap(); if context.powerd_session.is_none() { log::warn!("No powerd session!"); return; } if let (Some(pending_suspend_imminent), Some(powerd_session)) = if let (Some(pending_suspend_imminent), Some(powerd_session)) = (&context.pending_suspend_imminent, &context.powerd_session) (&context.pending_suspend_imminent, &context.powerd_session) { { Loading @@ -133,8 +138,21 @@ impl ISuspendCallback for SuspendCallback { powerd_session.delay_id, powerd_session.delay_id, pending_suspend_imminent.get_suspend_id(), pending_suspend_imminent.get_suspend_id(), ); ); } else if let (Some(adapter_suspend_dbus), None) = (&context.adapter_suspend_dbus, &context.pending_suspend_imminent) { log::info!("Suspend was aborted (imminent signal missing), so calling resume"); let mut suspend_dbus_rpc = adapter_suspend_dbus.rpc.clone(); tokio::spawn(async move { let result = suspend_dbus_rpc.resume().await; log::debug!("Adapter resume call, success = {}", result.unwrap_or(false)); }); } else { } else { log::warn!("Suspend ready but no SuspendImminent signal or powerd session"); log::warn!( "Suspend ready but powerd session valid={}, adapter available={}.", context.powerd_session.is_some(), context.adapter_suspend_dbus.is_some() ); } } } } } } Loading Loading @@ -498,11 +516,13 @@ impl PowerdSuspendManager { fn on_suspend_done(&mut self, suspend_done: SuspendDone) { fn on_suspend_done(&mut self, suspend_done: SuspendDone) { // powerd is telling us that suspend is done (system has resumed), so we tell btadapterd // powerd is telling us that suspend is done (system has resumed), so we tell btadapterd // to resume too. // to resume too. // powerd also sends the suspend done signal when the suspend is aborted. The suspend // imminent signal is cancelled here, so the cleanup is done after the suspend is ready. log::debug!("SuspendDone received: {:?}", suspend_done); log::debug!("SuspendDone received: {:?}", suspend_done); if self.context.lock().unwrap().pending_suspend_imminent.is_none() { if self.context.lock().unwrap().pending_suspend_imminent.is_none() { log::warn!("Receveid SuspendDone signal when there is no pending SuspendImminent"); log::warn!("Received SuspendDone signal when there is no pending SuspendImminent"); } } self.context.lock().unwrap().pending_suspend_imminent = None; self.context.lock().unwrap().pending_suspend_imminent = None; Loading system/gd/rust/linux/stack/src/suspend.rs +23 −5 Original line number Original line Diff line number Diff line Loading @@ -231,6 +231,8 @@ impl ISuspend for Suspend { } } fn suspend(&mut self, suspend_type: SuspendType, suspend_id: i32) { fn suspend(&mut self, suspend_type: SuspendType, suspend_id: i32) { // Set suspend state as true, prevent an early resume. self.suspend_state.lock().unwrap().suspend_expected = true; // Set suspend event mask // Set suspend event mask self.intf.lock().unwrap().set_default_event_mask_except(MASKED_EVENTS_FOR_SUSPEND, 0u64); self.intf.lock().unwrap().set_default_event_mask_except(MASKED_EVENTS_FOR_SUSPEND, 0u64); Loading Loading @@ -269,9 +271,7 @@ impl ISuspend for Suspend { _ => {} _ => {} } } self.suspend_state.lock().unwrap().le_rand_expected = true; self.suspend_state.lock().unwrap().le_rand_expected = true; self.suspend_state.lock().unwrap().suspend_expected = true; self.suspend_state.lock().unwrap().suspend_id = Some(suspend_id); self.suspend_state.lock().unwrap().suspend_id = Some(suspend_id); self.bt.lock().unwrap().le_rand(); if let Some(join_handle) = &self.suspend_timeout_joinhandle { if let Some(join_handle) = &self.suspend_timeout_joinhandle { join_handle.abort(); join_handle.abort(); Loading @@ -283,16 +283,25 @@ impl ISuspend for Suspend { self.suspend_timeout_joinhandle = Some(tokio::spawn(async move { self.suspend_timeout_joinhandle = Some(tokio::spawn(async move { tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await; tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await; log::error!("Suspend did not complete in 2 seconds, continuing anyway."); log::error!("Suspend did not complete in 2 seconds, continuing anyway."); suspend_state.lock().unwrap().le_rand_expected = false; suspend_state.lock().unwrap().le_rand_expected = false; suspend_state.lock().unwrap().suspend_expected = false; suspend_state.lock().unwrap().suspend_expected = false; tokio::spawn(async move { tokio::spawn(async move { let _result = tx.send(Message::SuspendReady(suspend_id)).await; let _result = tx.send(Message::SuspendReady(suspend_id)).await; }); }); })); })); // Call LE Rand at the end of suspend. The callback of LE Rand will reset the // suspend state, cancel the suspend timeout and send suspend ready signal. self.bt.lock().unwrap().le_rand(); } } fn resume(&mut self) -> bool { fn resume(&mut self) -> bool { // Suspend is not ready (e.g. aborted early), delay cleanup after SuspendReady. if self.suspend_state.lock().unwrap().suspend_expected == true { log::error!("Suspend is expected but not ready, abort resume."); return false; } // Suspend ID state 0: NoRecord, 1: Recorded // Suspend ID state 0: NoRecord, 1: Recorded let suspend_id_state = match self.suspend_state.lock().unwrap().suspend_id { let suspend_id_state = match self.suspend_state.lock().unwrap().suspend_id { None => { None => { Loading Loading @@ -362,7 +371,6 @@ impl ISuspend for Suspend { self.suspend_state.lock().unwrap().le_rand_expected = true; self.suspend_state.lock().unwrap().le_rand_expected = true; self.suspend_state.lock().unwrap().resume_expected = true; self.suspend_state.lock().unwrap().resume_expected = true; self.bt.lock().unwrap().le_rand(); let tx = self.tx.clone(); let tx = self.tx.clone(); let suspend_state = self.suspend_state.clone(); let suspend_state = self.suspend_state.clone(); Loading @@ -378,6 +386,10 @@ impl ISuspend for Suspend { }); }); })); })); // Call LE Rand at the end of resume. The callback of LE Rand will reset the // resume state and send resume ready signal. self.bt.lock().unwrap().le_rand(); true true } } } } Loading @@ -400,13 +412,19 @@ impl BtifBluetoothCallbacks for Suspend { let suspend_id = self.suspend_state.lock().unwrap().suspend_id.unwrap(); let suspend_id = self.suspend_state.lock().unwrap().suspend_id.unwrap(); if self.suspend_state.lock().unwrap().suspend_expected { if self.suspend_state.lock().unwrap().suspend_expected { self.suspend_state.lock().unwrap().suspend_expected = false; let suspend_state = self.suspend_state.clone(); let tx = self.tx.clone(); let tx = self.tx.clone(); tokio::spawn(async move { tokio::spawn(async move { // TODO(b/286268874) Add a short delay because HCI commands are not // synchronized. LE Rand is the last command, so wait for other // commands to finish. Remove after synchronization is fixed. tokio::time::sleep(tokio::time::Duration::from_millis( tokio::time::sleep(tokio::time::Duration::from_millis( LE_RAND_CB_SUSPEND_READY_DELAY_MS, LE_RAND_CB_SUSPEND_READY_DELAY_MS, )) )) .await; .await; // TODO(b/286268874) Reset suspend state after the delay. Prevent // resume until the suspend ready signal is sent. suspend_state.lock().unwrap().suspend_expected = false; let _result = tx.send(Message::SuspendReady(suspend_id)).await; let _result = tx.send(Message::SuspendReady(suspend_id)).await; }); }); } } Loading Loading
system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs +22 −2 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,11 @@ impl ISuspendCallback for SuspendCallback { { { let context = self.context.lock().unwrap(); let context = self.context.lock().unwrap(); if context.powerd_session.is_none() { log::warn!("No powerd session!"); return; } if let (Some(pending_suspend_imminent), Some(powerd_session)) = if let (Some(pending_suspend_imminent), Some(powerd_session)) = (&context.pending_suspend_imminent, &context.powerd_session) (&context.pending_suspend_imminent, &context.powerd_session) { { Loading @@ -133,8 +138,21 @@ impl ISuspendCallback for SuspendCallback { powerd_session.delay_id, powerd_session.delay_id, pending_suspend_imminent.get_suspend_id(), pending_suspend_imminent.get_suspend_id(), ); ); } else if let (Some(adapter_suspend_dbus), None) = (&context.adapter_suspend_dbus, &context.pending_suspend_imminent) { log::info!("Suspend was aborted (imminent signal missing), so calling resume"); let mut suspend_dbus_rpc = adapter_suspend_dbus.rpc.clone(); tokio::spawn(async move { let result = suspend_dbus_rpc.resume().await; log::debug!("Adapter resume call, success = {}", result.unwrap_or(false)); }); } else { } else { log::warn!("Suspend ready but no SuspendImminent signal or powerd session"); log::warn!( "Suspend ready but powerd session valid={}, adapter available={}.", context.powerd_session.is_some(), context.adapter_suspend_dbus.is_some() ); } } } } } } Loading Loading @@ -498,11 +516,13 @@ impl PowerdSuspendManager { fn on_suspend_done(&mut self, suspend_done: SuspendDone) { fn on_suspend_done(&mut self, suspend_done: SuspendDone) { // powerd is telling us that suspend is done (system has resumed), so we tell btadapterd // powerd is telling us that suspend is done (system has resumed), so we tell btadapterd // to resume too. // to resume too. // powerd also sends the suspend done signal when the suspend is aborted. The suspend // imminent signal is cancelled here, so the cleanup is done after the suspend is ready. log::debug!("SuspendDone received: {:?}", suspend_done); log::debug!("SuspendDone received: {:?}", suspend_done); if self.context.lock().unwrap().pending_suspend_imminent.is_none() { if self.context.lock().unwrap().pending_suspend_imminent.is_none() { log::warn!("Receveid SuspendDone signal when there is no pending SuspendImminent"); log::warn!("Received SuspendDone signal when there is no pending SuspendImminent"); } } self.context.lock().unwrap().pending_suspend_imminent = None; self.context.lock().unwrap().pending_suspend_imminent = None; Loading
system/gd/rust/linux/stack/src/suspend.rs +23 −5 Original line number Original line Diff line number Diff line Loading @@ -231,6 +231,8 @@ impl ISuspend for Suspend { } } fn suspend(&mut self, suspend_type: SuspendType, suspend_id: i32) { fn suspend(&mut self, suspend_type: SuspendType, suspend_id: i32) { // Set suspend state as true, prevent an early resume. self.suspend_state.lock().unwrap().suspend_expected = true; // Set suspend event mask // Set suspend event mask self.intf.lock().unwrap().set_default_event_mask_except(MASKED_EVENTS_FOR_SUSPEND, 0u64); self.intf.lock().unwrap().set_default_event_mask_except(MASKED_EVENTS_FOR_SUSPEND, 0u64); Loading Loading @@ -269,9 +271,7 @@ impl ISuspend for Suspend { _ => {} _ => {} } } self.suspend_state.lock().unwrap().le_rand_expected = true; self.suspend_state.lock().unwrap().le_rand_expected = true; self.suspend_state.lock().unwrap().suspend_expected = true; self.suspend_state.lock().unwrap().suspend_id = Some(suspend_id); self.suspend_state.lock().unwrap().suspend_id = Some(suspend_id); self.bt.lock().unwrap().le_rand(); if let Some(join_handle) = &self.suspend_timeout_joinhandle { if let Some(join_handle) = &self.suspend_timeout_joinhandle { join_handle.abort(); join_handle.abort(); Loading @@ -283,16 +283,25 @@ impl ISuspend for Suspend { self.suspend_timeout_joinhandle = Some(tokio::spawn(async move { self.suspend_timeout_joinhandle = Some(tokio::spawn(async move { tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await; tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await; log::error!("Suspend did not complete in 2 seconds, continuing anyway."); log::error!("Suspend did not complete in 2 seconds, continuing anyway."); suspend_state.lock().unwrap().le_rand_expected = false; suspend_state.lock().unwrap().le_rand_expected = false; suspend_state.lock().unwrap().suspend_expected = false; suspend_state.lock().unwrap().suspend_expected = false; tokio::spawn(async move { tokio::spawn(async move { let _result = tx.send(Message::SuspendReady(suspend_id)).await; let _result = tx.send(Message::SuspendReady(suspend_id)).await; }); }); })); })); // Call LE Rand at the end of suspend. The callback of LE Rand will reset the // suspend state, cancel the suspend timeout and send suspend ready signal. self.bt.lock().unwrap().le_rand(); } } fn resume(&mut self) -> bool { fn resume(&mut self) -> bool { // Suspend is not ready (e.g. aborted early), delay cleanup after SuspendReady. if self.suspend_state.lock().unwrap().suspend_expected == true { log::error!("Suspend is expected but not ready, abort resume."); return false; } // Suspend ID state 0: NoRecord, 1: Recorded // Suspend ID state 0: NoRecord, 1: Recorded let suspend_id_state = match self.suspend_state.lock().unwrap().suspend_id { let suspend_id_state = match self.suspend_state.lock().unwrap().suspend_id { None => { None => { Loading Loading @@ -362,7 +371,6 @@ impl ISuspend for Suspend { self.suspend_state.lock().unwrap().le_rand_expected = true; self.suspend_state.lock().unwrap().le_rand_expected = true; self.suspend_state.lock().unwrap().resume_expected = true; self.suspend_state.lock().unwrap().resume_expected = true; self.bt.lock().unwrap().le_rand(); let tx = self.tx.clone(); let tx = self.tx.clone(); let suspend_state = self.suspend_state.clone(); let suspend_state = self.suspend_state.clone(); Loading @@ -378,6 +386,10 @@ impl ISuspend for Suspend { }); }); })); })); // Call LE Rand at the end of resume. The callback of LE Rand will reset the // resume state and send resume ready signal. self.bt.lock().unwrap().le_rand(); true true } } } } Loading @@ -400,13 +412,19 @@ impl BtifBluetoothCallbacks for Suspend { let suspend_id = self.suspend_state.lock().unwrap().suspend_id.unwrap(); let suspend_id = self.suspend_state.lock().unwrap().suspend_id.unwrap(); if self.suspend_state.lock().unwrap().suspend_expected { if self.suspend_state.lock().unwrap().suspend_expected { self.suspend_state.lock().unwrap().suspend_expected = false; let suspend_state = self.suspend_state.clone(); let tx = self.tx.clone(); let tx = self.tx.clone(); tokio::spawn(async move { tokio::spawn(async move { // TODO(b/286268874) Add a short delay because HCI commands are not // synchronized. LE Rand is the last command, so wait for other // commands to finish. Remove after synchronization is fixed. tokio::time::sleep(tokio::time::Duration::from_millis( tokio::time::sleep(tokio::time::Duration::from_millis( LE_RAND_CB_SUSPEND_READY_DELAY_MS, LE_RAND_CB_SUSPEND_READY_DELAY_MS, )) )) .await; .await; // TODO(b/286268874) Reset suspend state after the delay. Prevent // resume until the suspend ready signal is sent. suspend_state.lock().unwrap().suspend_expected = false; let _result = tx.send(Message::SuspendReady(suspend_id)).await; let _result = tx.send(Message::SuspendReady(suspend_id)).await; }); }); } } Loading