Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a01121f8 authored by Zhengping Jiang's avatar Zhengping Jiang Committed by Gerrit Code Review
Browse files

Merge "floss: start resume if suspend is aborted" into main

parents dbebad04 2c0570b5
Loading
Loading
Loading
Loading
+22 −2
Original line number Original line Diff line number Diff line
@@ -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)
            {
            {
@@ -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()
                );
            }
            }
        }
        }
    }
    }
@@ -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;
+23 −5
Original line number Original line Diff line number Diff line
@@ -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);


@@ -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();
@@ -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 => {
@@ -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();
@@ -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
    }
    }
}
}
@@ -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;
            });
            });
        }
        }