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

Commit ff83a750 authored by Bryce Lee's avatar Bryce Lee
Browse files

Move LowLightMonitor operations to background thread.

LowLightMonitor contains a number of callbacks that are triggered by
events such as screen turning on and off (triggered during unfolding as
well). This changelist moves these operations to a background thread to
not block the main thread.

Test: atest LowLightMonitorTest
Flag: EXEMPT bugfix
Fixes: 394520234
Change-Id: I435c21e2c1e0827c8de24cd0737cfa55c1fab403
parent a708b619
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -30,8 +30,9 @@ import static org.mockito.Mockito.when;

import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.dream.lowlight.LowLightDreamManager;
@@ -39,6 +40,8 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.shared.condition.Condition;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;

import dagger.Lazy;

@@ -53,7 +56,8 @@ import org.mockito.MockitoAnnotations;
import java.util.Set;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper()
public class LowLightMonitorTest extends SysuiTestCase {

    @Mock
@@ -78,6 +82,8 @@ public class LowLightMonitorTest extends SysuiTestCase {
    @Mock
    private ComponentName mDreamComponent;

    FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());

    Condition mCondition = mock(Condition.class);
    Set<Condition> mConditionSet = Set.of(mCondition);

@@ -91,12 +97,13 @@ public class LowLightMonitorTest extends SysuiTestCase {
        when(mLazyConditions.get()).thenReturn(mConditionSet);
        mLowLightMonitor = new LowLightMonitor(mLowLightDreamManagerLazy,
            mMonitor, mLazyConditions, mScreenLifecycle, mLogger, mDreamComponent,
                mPackageManager);
                mPackageManager, mBackgroundExecutor);
    }

    @Test
    public void testSetAmbientLowLightWhenInLowLight() {
        mLowLightMonitor.onConditionsChanged(true);
        mBackgroundExecutor.runAllReady();
        // Verify setting low light when condition is true
        verify(mLowLightDreamManager).setAmbientLightMode(AMBIENT_LIGHT_MODE_LOW_LIGHT);
    }
@@ -105,6 +112,7 @@ public class LowLightMonitorTest extends SysuiTestCase {
    public void testExitAmbientLowLightWhenNotInLowLight() {
        mLowLightMonitor.onConditionsChanged(true);
        mLowLightMonitor.onConditionsChanged(false);
        mBackgroundExecutor.runAllReady();
        // Verify ambient light toggles back to light mode regular
        verify(mLowLightDreamManager).setAmbientLightMode(AMBIENT_LIGHT_MODE_REGULAR);
    }
@@ -112,6 +120,7 @@ public class LowLightMonitorTest extends SysuiTestCase {
    @Test
    public void testStartMonitorLowLightConditionsWhenScreenTurnsOn() {
        mLowLightMonitor.onScreenTurnedOn();
        mBackgroundExecutor.runAllReady();

        // Verify subscribing to low light conditions monitor when screen turns on.
        verify(mMonitor).addSubscription(any());
@@ -125,6 +134,7 @@ public class LowLightMonitorTest extends SysuiTestCase {

        // Verify removing subscription when screen turns off.
        mLowLightMonitor.onScreenTurnedOff();
        mBackgroundExecutor.runAllReady();
        verify(mMonitor).removeSubscription(token);
    }

@@ -135,6 +145,7 @@ public class LowLightMonitorTest extends SysuiTestCase {

        mLowLightMonitor.onScreenTurnedOn();
        mLowLightMonitor.onScreenTurnedOn();
        mBackgroundExecutor.runAllReady();
        // Verify subscription is only added once.
        verify(mMonitor, times(1)).addSubscription(any());
    }
@@ -146,6 +157,7 @@ public class LowLightMonitorTest extends SysuiTestCase {

        mLowLightMonitor.onScreenTurnedOn();
        mLowLightMonitor.onScreenTurnedOn();
        mBackgroundExecutor.runAllReady();
        Set<Condition> conditions = captureConditions();
        // Verify Monitor is subscribed to the expected conditions
        assertThat(conditions).isEqualTo(mConditionSet);
@@ -154,7 +166,7 @@ public class LowLightMonitorTest extends SysuiTestCase {
    @Test
    public void testNotUnsubscribeIfNotSubscribedWhenScreenTurnsOff() {
        mLowLightMonitor.onScreenTurnedOff();

        mBackgroundExecutor.runAllReady();
        // Verify doesn't remove subscription since there is none.
        verify(mMonitor, never()).removeSubscription(any());
    }
@@ -163,6 +175,7 @@ public class LowLightMonitorTest extends SysuiTestCase {
    public void testSubscribeIfScreenIsOnWhenStarting() {
        when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
        mLowLightMonitor.start();
        mBackgroundExecutor.runAllReady();
        // Verify to add subscription on start if the screen state is on
        verify(mMonitor, times(1)).addSubscription(any());
    }
@@ -170,9 +183,11 @@ public class LowLightMonitorTest extends SysuiTestCase {
    @Test
    public void testNoSubscribeIfDreamNotPresent() {
        LowLightMonitor lowLightMonitor = new LowLightMonitor(mLowLightDreamManagerLazy,
                mMonitor, mLazyConditions, mScreenLifecycle, mLogger, null, mPackageManager);
                mMonitor, mLazyConditions, mScreenLifecycle, mLogger, null, mPackageManager,
                mBackgroundExecutor);
        when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
        lowLightMonitor.start();
        mBackgroundExecutor.runAllReady();
        verify(mScreenLifecycle, never()).addObserver(any());
    }

+52 −37
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.pm.PackageManager;
import androidx.annotation.Nullable;

import com.android.dream.lowlight.LowLightDreamManager;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.SystemUser;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.shared.condition.Condition;
@@ -36,6 +37,7 @@ import com.android.systemui.util.condition.ConditionalCoreStartable;
import dagger.Lazy;

import java.util.Set;
import java.util.concurrent.Executor;

import javax.inject.Inject;
import javax.inject.Named;
@@ -59,6 +61,8 @@ public class LowLightMonitor extends ConditionalCoreStartable implements Monitor

    private final PackageManager mPackageManager;

    private final Executor mExecutor;

    @Inject
    public LowLightMonitor(Lazy<LowLightDreamManager> lowLightDreamManager,
            @SystemUser Monitor conditionsMonitor,
@@ -66,7 +70,8 @@ public class LowLightMonitor extends ConditionalCoreStartable implements Monitor
            ScreenLifecycle screenLifecycle,
            LowLightLogger lowLightLogger,
            @Nullable @Named(LOW_LIGHT_DREAM_SERVICE) ComponentName lowLightDreamService,
            PackageManager packageManager) {
            PackageManager packageManager,
            @Background Executor backgroundExecutor) {
        super(conditionsMonitor);
        mLowLightDreamManager = lowLightDreamManager;
        mConditionsMonitor = conditionsMonitor;
@@ -75,18 +80,22 @@ public class LowLightMonitor extends ConditionalCoreStartable implements Monitor
        mLogger = lowLightLogger;
        mLowLightDreamService = lowLightDreamService;
        mPackageManager = packageManager;
        mExecutor = backgroundExecutor;
    }

    @Override
    public void onConditionsChanged(boolean allConditionsMet) {
        mExecutor.execute(() -> {
            mLogger.d(TAG, "Low light enabled: " + allConditionsMet);

            mLowLightDreamManager.get().setAmbientLightMode(allConditionsMet
                    ? AMBIENT_LIGHT_MODE_LOW_LIGHT : AMBIENT_LIGHT_MODE_REGULAR);
        });
    }

    @Override
    public void onScreenTurnedOn() {
        mExecutor.execute(() -> {
            if (mSubscriptionToken == null) {
                mLogger.d(TAG, "Screen turned on. Subscribing to low light conditions.");

@@ -95,21 +104,25 @@ public class LowLightMonitor extends ConditionalCoreStartable implements Monitor
                                .addConditions(mLowLightConditions.get())
                                .build());
            }
        });
    }


    @Override
    public void onScreenTurnedOff() {
        mExecutor.execute(() -> {
            if (mSubscriptionToken != null) {
                mLogger.d(TAG, "Screen turned off. Removing subscription to low light conditions.");

                mConditionsMonitor.removeSubscription(mSubscriptionToken);
                mSubscriptionToken = null;
            }
        });
    }

    @Override
    protected void onStart() {
        mExecutor.execute(() -> {
            if (mLowLightDreamService != null) {
                // Note that the dream service is disabled by default. This prevents the dream from
                // appearing in settings on devices that don't have it explicitly excluded (done in
@@ -129,5 +142,7 @@ public class LowLightMonitor extends ConditionalCoreStartable implements Monitor
            if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
                onScreenTurnedOn();
            }
        });

    }
}