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

Commit c4b166ab authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Disallow dreaming when auto projected display is active" into main

parents 3d57c36d 60392de5
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -110,3 +110,13 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "disallow_dream_on_auto_projection"
    namespace: "systemui"
    description: "Disallows dreaming when Android Auto projected display is active"
    bug: "413508543"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
 No newline at end of file
+13 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.os.BatteryManager.EXTRA_CHARGING_STATUS;
import static android.service.dreams.Flags.allowDreamWhenPostured;
import static android.service.dreams.Flags.allowDreamWithChargeLimit;
import static android.service.dreams.Flags.cleanupDreamSettingsOnUninstall;
import static android.service.dreams.Flags.disallowDreamOnAutoProjection;
import static android.service.dreams.Flags.dreamHandlesBeingObscured;
import static android.service.dreams.Flags.dreamsV2;

@@ -35,6 +36,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.IAppTask;
import android.app.TaskInfo;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -136,6 +138,7 @@ public final class DreamManagerService extends SystemService {
    private final Handler mHandler;
    private final DreamController mController;
    private final PowerManager mPowerManager;
    private final UiModeManager mUiModeManager;
    private final PowerManagerInternal mPowerManagerInternal;
    private final BatteryManagerInternal mBatteryManagerInternal;
    private final PowerManager.WakeLock mDozeWakeLock;
@@ -276,6 +279,7 @@ public final class DreamManagerService extends SystemService {

        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mPowerManagerInternal = getLocalService(PowerManagerInternal.class);
        mUiModeManager = (UiModeManager) context.getSystemService(Context.UI_MODE_SERVICE);
        mAtmInternal = getLocalService(ActivityTaskManagerInternal.class);
        mPmInternal = getLocalService(PackageManagerInternal.class);
        mUserManager = context.getSystemService(UserManager.class);
@@ -597,7 +601,8 @@ public final class DreamManagerService extends SystemService {
    }

    /** Whether dreaming can start given user settings and the current dock/charge state. */
    private boolean canStartDreamingInternal(boolean isScreenOn) {
    @VisibleForTesting
    boolean canStartDreamingInternal(boolean isScreenOn) {
        synchronized (mLock) {
            // Can't start dreaming if we are already dreaming and the dream has focus. If we are
            // dreaming but the dream does not have focus, then the dream can be brought to the
@@ -606,6 +611,13 @@ public final class DreamManagerService extends SystemService {
                return false;
            }

            if (disallowDreamOnAutoProjection()
                    && (mUiModeManager.getActiveProjectionTypes()
                        & UiModeManager.PROJECTION_TYPE_AUTOMOTIVE) != 0) {
                // Don't dream when connected to Android Auto unit as dreams can't start anyways.
                return false;
            }

            if (!mDreamsEnabledSetting) {
                return false;
            }
+73 −1
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package com.android.server.dreams;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.BatteryManager.EXTRA_CHARGING_STATUS;
import static android.service.dreams.Flags.FLAG_DREAMS_V2;
import static android.service.dreams.Flags.FLAG_ALLOW_DREAM_WITH_CHARGE_LIMIT;
import static android.service.dreams.Flags.FLAG_DISALLOW_DREAM_ON_AUTO_PROJECTION;
import static android.service.dreams.Flags.FLAG_DREAMS_V2;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

@@ -32,8 +34,11 @@ import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.Manifest;
import android.app.ActivityManagerInternal;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.hardware.health.BatteryChargingState;
@@ -84,6 +89,8 @@ public class DreamManagerServiceTest {
    @Mock
    private PowerManagerInternal mPowerManagerInternalMock;
    @Mock
    private UiModeManager mUiModeManagerMock;
    @Mock
    private UserManager mUserManagerMock;

    @Rule
@@ -98,6 +105,10 @@ public class DreamManagerServiceTest {
    public void setUp() throws Exception {
        mTestHandler = new TestHandler(/* callback= */ null);
        MockitoAnnotations.initMocks(this);

        mContext.getTestablePermissions().setPermission(
                Manifest.permission.READ_PROJECTION_STATE, PERMISSION_GRANTED);

        mContextSpy = spy(mContext);

        mLocalServiceKeeperRule.overrideLocalService(ActivityManagerInternal.class,
@@ -117,6 +128,7 @@ public class DreamManagerServiceTest {
                Settings.Secure.SCREENSAVER_RESTRICT_TO_WIRELESS_CHARGING, 0);

        when(mContextSpy.getSystemService(UserManager.class)).thenReturn(mUserManagerMock);
        when(mContextSpy.getSystemService(Context.UI_MODE_SERVICE)).thenReturn(mUiModeManagerMock);
    }

    private DreamManagerService createService() {
@@ -145,6 +157,66 @@ public class DreamManagerServiceTest {
        assertThat(service.dreamsEnabled()).isFalse();
    }

    @Test
    public void testCanStartDreaming_charging() {
        // Enable dreaming while charging only.
        Settings.Secure.putIntForUser(mContextSpy.getContentResolver(),
                Settings.Secure.SCREENSAVER_ENABLED, 1, UserHandle.USER_CURRENT);
        Settings.Secure.putIntForUser(mContextSpy.getContentResolver(),
                Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1, UserHandle.USER_CURRENT);

        // Set up preconditions.
        when(mUserManagerMock.isUserUnlocked()).thenReturn(true);

        // Device is charging.
        when(mBatteryManagerInternal.isPowered(anyInt())).thenReturn(true);

        // Initialize service so settings are read.
        final DreamManagerService service = createService();
        service.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

        // Battery changed event is received.
        ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
                BroadcastReceiver.class);
        verify(mContextSpy).registerReceiver(receiverCaptor.capture(),
                argThat((arg) -> arg.hasAction(Intent.ACTION_BATTERY_CHANGED)));
        receiverCaptor.getValue().onReceive(mContext, new Intent());

        // Can start dreaming is true.
        assertThat(service.canStartDreamingInternal(/*isScreenOn=*/ true)).isTrue();
    }

    @EnableFlags(FLAG_DISALLOW_DREAM_ON_AUTO_PROJECTION)
    @Test
    public void testCanStartDreaming_falseWithProjectedDisplay() {
        // Enable dreaming while charging only.
        Settings.Secure.putIntForUser(mContextSpy.getContentResolver(),
                Settings.Secure.SCREENSAVER_ENABLED, 1, UserHandle.USER_CURRENT);
        Settings.Secure.putIntForUser(mContextSpy.getContentResolver(),
                Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1, UserHandle.USER_CURRENT);

        // Device is charging.
        when(mBatteryManagerInternal.isPowered(anyInt())).thenReturn(true);

        // Connected to Android Auto.
        when(mUiModeManagerMock.getActiveProjectionTypes())
                .thenReturn(UiModeManager.PROJECTION_TYPE_NONE);

        // Initialize service so settings are read.
        final DreamManagerService service = createService();
        service.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

        // Battery changed event is received.
        ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
                BroadcastReceiver.class);
        verify(mContextSpy).registerReceiver(receiverCaptor.capture(),
                argThat((arg) -> arg.hasAction(Intent.ACTION_BATTERY_CHANGED)));
        receiverCaptor.getValue().onReceive(mContext, new Intent());

        // Can start dreaming is true.
        assertThat(service.canStartDreamingInternal(/*isScreenOn=*/ true)).isFalse();
    }

    @Test
    public void testDreamConditionActive_onDock() {
        // Enable dreaming on dock.