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

Commit 7ec407e8 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/34151544'] into 25Q2-release.

Change-Id: I369b8e3af69602f0c460ac3efbe1a1bd95cde59b
parents c47227da 0e27558a
Loading
Loading
Loading
Loading
+34 −25
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.app.UiModeManager.ContrastUtils.CONTRAST_DEFAULT_VALUE;
import static android.app.UiModeManager.DEFAULT_PRIORITY;
import static android.app.UiModeManager.FORCE_INVERT_TYPE_DARK;
import static android.app.UiModeManager.FORCE_INVERT_TYPE_OFF;
import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT;
import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF;
import static android.app.UiModeManager.MODE_NIGHT_AUTO;
import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
@@ -99,9 +100,10 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;

import androidx.annotation.VisibleForTesting;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.DisableCarModeActivity;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
@@ -480,6 +482,11 @@ final class UiModeManagerService extends SystemService {
        mCurrentUser = currentUserId;
    }

    @VisibleForTesting
    Boolean[] getNightModeOverrides() {
        return new Boolean[]{mOverrideNightModeOn, mOverrideNightModeOff};
    }

    @Override
    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
        mCurrentUser = to.getUserIdentifier();
@@ -1596,6 +1603,9 @@ final class UiModeManagerService extends SystemService {
    private void onCustomTimeUpdated(int user) {
        persistNightMode(user);
        if (mNightMode.get() != MODE_NIGHT_CUSTOM) return;

        synchronized (mLock) {
            resetNightModeOverrideLocked();
            if (shouldApplyAutomaticChangesImmediately()) {
                unregisterDeviceInactiveListenerLocked();
                updateLocked(0, 0);
@@ -1603,6 +1613,7 @@ final class UiModeManagerService extends SystemService {
                registerDeviceInactiveListenerLocked();
            }
        }
    }

    void dumpImpl(PrintWriter pw) {
        synchronized (mLock) {
@@ -1871,6 +1882,8 @@ final class UiModeManagerService extends SystemService {
            unregisterTimeChangeEvent();
        }

        updateForceInvertStates();

        // Override night mode in power save mode if not in car mode
        if (mPowerSave && !mCarModeEnabled && !mCar) {
            uiMode &= ~Configuration.UI_MODE_NIGHT_NO;
@@ -2198,25 +2211,21 @@ final class UiModeManagerService extends SystemService {
    }

    private void updateComputedNightModeLocked(boolean activate) {
        boolean newComputedValue = activate;
        boolean appliedOverrides = false;
        if (mNightMode.get() != MODE_NIGHT_YES && mNightMode.get() != UiModeManager.MODE_NIGHT_NO) {
            if (mOverrideNightModeOn && !newComputedValue) {
                newComputedValue = true;
            } else if (mOverrideNightModeOff && newComputedValue) {
                newComputedValue = false;
            }
            appliedOverrides = true;
        }

        // Computes final night mode values based on Attention Mode.
        mComputedNightMode = switch (mAttentionModeThemeOverlay) {
            case (UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT) -> true;
            case (UiModeManager.MODE_ATTENTION_THEME_OVERLAY_DAY) -> false;
            default -> newComputedValue; // case OFF
        };
        mComputedNightMode = activate;

        if (appliedOverrides) {
        if (mAttentionModeThemeOverlay != MODE_ATTENTION_THEME_OVERLAY_OFF) {
            mComputedNightMode = mAttentionModeThemeOverlay == MODE_ATTENTION_THEME_OVERLAY_NIGHT;
            return;
        }
        if (mNightMode.get() == MODE_NIGHT_YES || mNightMode.get() == UiModeManager.MODE_NIGHT_NO) {
            return;
        }
        if (mOverrideNightModeOn && !mComputedNightMode) {
            mComputedNightMode = true;
            return;
        }
        if (mOverrideNightModeOff && mComputedNightMode) {
            mComputedNightMode = false;
            return;
        }

@@ -2460,7 +2469,7 @@ final class UiModeManagerService extends SystemService {
        }
    }

    @VisibleForTesting
    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
    public static class Injector {
        public int getCallingUid() {
            return Binder.getCallingUid();
+56 −0
Original line number Diff line number Diff line
@@ -910,6 +910,62 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
                .setExact(anyInt(), anyLong(), anyString(), any(), any());
    }

    @Test
    public void customTime_clearsOverrides_whenOverrideOnIsSet() throws RemoteException {
        when(mPowerManager.isInteractive()).thenReturn(false);

        mService.setNightMode(MODE_NIGHT_CUSTOM);
        LocalTime scheduleStart = LocalTime.now().plusHours(2);
        LocalTime scheduleEnd = LocalTime.now().plusHours(3);
        mService.setCustomNightModeStart(scheduleStart.toNanoOfDay() / 1000);
        mService.setCustomNightModeEnd(scheduleEnd.toNanoOfDay() / 1000);
        assertThat(isNightModeActivated()).isFalse();

        mService.setNightModeActivated(true);

        //Verify override is set and night mode is ON due to override
        Boolean[] overrides = mUiManagerService.getNightModeOverrides();
        assertThat(overrides[0]).isTrue();  // mOverrideNightModeOn
        assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff
        assertThat(isNightModeActivated()).isTrue(); // Night mode is ON due to override

        LocalTime newStartTime = LocalTime.now().plusHours(1);
        mService.setCustomNightModeStart(newStartTime.toNanoOfDay() / 1000);

        // Verify overrides are cleared
        overrides = mUiManagerService.getNightModeOverrides();
        assertThat(overrides[0]).isFalse(); // mOverrideNightModeOn should be cleared
        assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff should be cleared
    }

    @Test
    public void customTime_clearsOverrides_whenOverrideOffIsSet() throws RemoteException {
        when(mPowerManager.isInteractive()).thenReturn(false);

        mService.setNightMode(MODE_NIGHT_CUSTOM);
        LocalTime scheduleStart = LocalTime.now().minusHours(2);
        LocalTime scheduleEnd = LocalTime.now().plusHours(3);
        mService.setCustomNightModeStart(scheduleStart.toNanoOfDay() / 1000);
        mService.setCustomNightModeEnd(scheduleEnd.toNanoOfDay() / 1000);
        assertThat(isNightModeActivated()).isTrue();

        mService.setNightModeActivated(false);

        //Verify override is set and night mode is OFF due to override
        Boolean[] overrides = mUiManagerService.getNightModeOverrides();
        assertThat(overrides[0]).isFalse();  // mOverrideNightModeOn
        assertThat(overrides[1]).isTrue(); // mOverrideNightModeOff
        assertThat(isNightModeActivated()).isFalse(); // Night mode is ON due to override

        LocalTime newEndTime = LocalTime.now().plusHours(1);
        mService.setCustomNightModeStart(newEndTime.toNanoOfDay() / 1000);

        // Verify overrides are cleared
        overrides = mUiManagerService.getNightModeOverrides();
        assertThat(overrides[0]).isFalse(); // mOverrideNightModeOn should be cleared
        assertThat(overrides[1]).isFalse(); // mOverrideNightModeOff should be cleared
    }

    @Test
    public void customTime_alarmSetInTheFutureWhenOn() throws RemoteException {
        LocalDateTime now = LocalDateTime.now();