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

Commit 909d3471 authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Disable hinge sensor while the screen is off

This allows to save some power while the device is unfolded but with screen off.

+ Avoiding registering more listeners if HingeSensorAngleProvider.start() is called multiple times sequentially without a `stop` in the middle. It seems that otherwise we would get duplicated callbacks.

+ Adding onScreenTurningOn and onScreenTurningOff callbacks to forward to Launcher (as only sysui is receiving them)

Bug: 240661156
Bug: 240374404
Test: DeviceFoldStateProviderTest
Change-Id: I40b77033690c2e708275ce49bbe156c781105a00
parent 3ad54047
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -100,4 +100,14 @@ oneway interface IOverviewProxy {
     * Sent when the desired dark intensity of the nav buttons has changed
     */
    void onNavButtonsDarkIntensityChanged(float darkIntensity) = 22;

     /**
      * Sent when screen started turning on.
      */
     void onScreenTurningOn() = 23;

     /**
      * Sent when screen started turning off.
      */
     void onScreenTurningOff() = 24;
}
+8 −0
Original line number Diff line number Diff line
@@ -41,4 +41,12 @@ class LifecycleScreenStatusProvider @Inject constructor(screenLifecycle: ScreenL
    override fun onScreenTurnedOn() {
        listeners.forEach(ScreenListener::onScreenTurnedOn)
    }

    override fun onScreenTurningOff() {
        listeners.forEach(ScreenListener::onScreenTurningOff)
    }

    override fun onScreenTurningOn(ignored: Runnable) {
        listeners.forEach(ScreenListener::onScreenTurningOn)
    }
}
+48 −18
Original line number Diff line number Diff line
@@ -638,12 +638,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
        // Listen for user setup
        startTracking();

        screenLifecycle.addObserver(new ScreenLifecycle.Observer() {
            @Override
            public void onScreenTurnedOn() {
                notifyScreenTurnedOn();
            }
        });
        screenLifecycle.addObserver(mLifecycleObserver);

        // Connect to the service
        updateEnabledState();
@@ -951,10 +946,12 @@ public class OverviewProxyService extends CurrentUserTracker implements
        }
    }

    private final ScreenLifecycle.Observer mLifecycleObserver = new ScreenLifecycle.Observer() {
        /**
         * Notifies the Launcher that screen turned on and ready to use
         */
    public void notifyScreenTurnedOn() {
        @Override
        public void onScreenTurnedOn() {
            try {
                if (mOverviewProxy != null) {
                    mOverviewProxy.onScreenTurnedOn();
@@ -962,10 +959,43 @@ public class OverviewProxyService extends CurrentUserTracker implements
                    Log.e(TAG_OPS, "Failed to get overview proxy for screen turned on event.");
                }
            } catch (RemoteException e) {
            Log.e(TAG_OPS, "Failed to call notifyScreenTurnedOn()", e);
                Log.e(TAG_OPS, "Failed to call onScreenTurnedOn()", e);
            }
        }

        /**
         * Notifies the Launcher that screen is starting to turn on.
         */
        @Override
        public void onScreenTurningOff() {
            try {
                if (mOverviewProxy != null) {
                    mOverviewProxy.onScreenTurningOff();
                } else {
                    Log.e(TAG_OPS, "Failed to get overview proxy for screen turning off event.");
                }
            } catch (RemoteException e) {
                Log.e(TAG_OPS, "Failed to call onScreenTurningOff()", e);
            }
        }

        /**
         * Notifies the Launcher that screen is starting to turn on.
         */
        @Override
        public void onScreenTurningOn(@NonNull Runnable ignored) {
            try {
                if (mOverviewProxy != null) {
                    mOverviewProxy.onScreenTurningOn();
                } else {
                    Log.e(TAG_OPS, "Failed to get overview proxy for screen turning on event.");
                }
            } catch (RemoteException e) {
                Log.e(TAG_OPS, "Failed to call onScreenTurningOn()", e);
            }
        }
    };

    void notifyToggleRecentApps() {
        for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
            mConnectionCallbacks.get(i).onToggleRecentApps();
+53 −4
Original line number Diff line number Diff line
@@ -30,13 +30,13 @@ import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import java.util.concurrent.Executor
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations

@RunWith(AndroidTestingRunner::class)
@SmallTest
@@ -331,6 +331,47 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
    }

    @Test
    fun screenOff_whileFolded_hingeAngleProviderRemainsOff() {
        setFoldState(folded = true)
        assertThat(testHingeAngleProvider.isStarted).isFalse()

        screenOnStatusProvider.notifyScreenTurningOff()

        assertThat(testHingeAngleProvider.isStarted).isFalse()
    }

    @Test
    fun screenOff_whileUnfolded_hingeAngleProviderStops() {
        setFoldState(folded = false)
        assertThat(testHingeAngleProvider.isStarted).isTrue()

        screenOnStatusProvider.notifyScreenTurningOff()

        assertThat(testHingeAngleProvider.isStarted).isFalse()
    }

    @Test
    fun screenOn_whileUnfoldedAndScreenOff_hingeAngleProviderStarted() {
        setFoldState(folded = false)
        screenOnStatusProvider.notifyScreenTurningOff()
        assertThat(testHingeAngleProvider.isStarted).isFalse()

        screenOnStatusProvider.notifyScreenTurningOn()

        assertThat(testHingeAngleProvider.isStarted).isTrue()
    }

    @Test
    fun screenOn_whileFolded_hingeAngleRemainsOff() {
        setFoldState(folded = true)
        assertThat(testHingeAngleProvider.isStarted).isFalse()

        screenOnStatusProvider.notifyScreenTurningOn()

        assertThat(testHingeAngleProvider.isStarted).isFalse()
    }

    private fun setupForegroundActivityType(isHomeActivity: Boolean?) {
        whenever(activityTypeProvider.isHomeActivity).thenReturn(isHomeActivity)
    }
@@ -391,6 +432,14 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
        fun notifyScreenTurnedOn() {
            callbacks.forEach { it.onScreenTurnedOn() }
        }

        fun notifyScreenTurningOn() {
            callbacks.forEach { it.onScreenTurningOn() }
        }

        fun notifyScreenTurningOff() {
            callbacks.forEach { it.onScreenTurningOff() }
        }
    }

    private class TestHingeAngleProvider : HingeAngleProvider {
@@ -398,11 +447,11 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
        var isStarted: Boolean = false

        override fun start() {
            isStarted = true;
            isStarted = true
        }

        override fun stop() {
            isStarted = false;
            isStarted = false
        }

        override fun addCallback(listener: Consumer<Float>) {
+20 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ constructor(
    private val halfOpenedTimeoutMillis: Int = config.halfFoldedTimeoutMillis

    private var isFolded = false
    private var isScreenOn = false
    private var isUnfoldHandled = true

    override fun start() {
@@ -198,6 +199,25 @@ constructor(
                isUnfoldHandled = true
            }
        }

        override fun onScreenTurningOn() {
            isScreenOn = true
            updateHingeAngleProviderState()
        }

        override fun onScreenTurningOff() {
            isScreenOn = false
            updateHingeAngleProviderState()
        }
    }

    /** While the screen is off or the device is folded, hinge angle updates are not needed. */
    private fun updateHingeAngleProviderState() {
        if (isScreenOn && !isFolded) {
            hingeAngleProvider.start()
        } else {
            hingeAngleProvider.stop()
        }
    }

    private inner class HingeAngleListener : Consumer<Float> {
Loading