Loading core/java/android/view/ViewRootImpl.java +45 −24 Original line number Diff line number Diff line Loading @@ -152,8 +152,6 @@ import android.annotation.UiContext; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ResourcesManager; import android.app.UiModeManager; import android.app.UiModeManager.ForceInvertStateChangeListener; import android.app.WindowConfiguration; import android.app.compat.CompatChanges; import android.app.servertransaction.WindowStateTransactionItem; Loading @@ -169,6 +167,7 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.database.ContentObserver; import android.graphics.BLASTBufferQueue; import android.graphics.Canvas; import android.graphics.Color; Loading Loading @@ -214,6 +213,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.os.Vibrator; import android.provider.Settings; import android.sysprop.DisplayProperties; import android.sysprop.ViewProperties; import android.text.TextUtils; Loading Loading @@ -469,8 +469,10 @@ public final class ViewRootImpl implements ViewParent, private CompatOnBackInvokedCallback mCompatOnBackInvokedCallback; @Nullable private ForceInvertStateChangeListener mForceInvertStateChangeListener; private ContentObserver mForceInvertObserver; private static final int INVALID_VALUE = Integer.MIN_VALUE; private int mForceInvertEnabled = INVALID_VALUE; /** * Callback for notifying about global configuration changes. */ Loading Loading @@ -552,8 +554,6 @@ public final class ViewRootImpl implements ViewParent, @UiContext public final Context mContext; private UiModeManager mUiModeManager; @UnsupportedAppUsage final IWindowSession mWindowSession; @NonNull Display mDisplay; Loading Loading @@ -1255,7 +1255,6 @@ public final class ViewRootImpl implements ViewParent, public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session, WindowLayout windowLayout) { mContext = context; mUiModeManager = context.getSystemService(UiModeManager.class); mWindowSession = session; mWindowLayout = windowLayout; mDisplay = display; Loading Loading @@ -1804,6 +1803,23 @@ public final class ViewRootImpl implements ViewParent, } } private boolean isForceInvertEnabled() { if (mForceInvertEnabled == INVALID_VALUE) { reloadForceInvertEnabled(); } return mForceInvertEnabled == 1; } private void reloadForceInvertEnabled() { if (forceInvertColor()) { mForceInvertEnabled = Settings.Secure.getIntForUser( mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* def= */ 0, UserHandle.myUserId()); } } /** * Register any kind of listeners if setView was success. */ Loading Loading @@ -1835,11 +1851,21 @@ public final class ViewRootImpl implements ViewParent, mBasePackageName); if (forceInvertColor()) { if (mForceInvertStateChangeListener == null) { mForceInvertStateChangeListener = forceInvertState -> updateForceDarkMode(); mUiModeManager.addForceInvertStateChangeListener(mExecutor, mForceInvertStateChangeListener); if (mForceInvertObserver == null) { mForceInvertObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { reloadForceInvertEnabled(); updateForceDarkMode(); } }; mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor( Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED ), false, mForceInvertObserver, UserHandle.myUserId()); } } } Loading @@ -1857,10 +1883,9 @@ public final class ViewRootImpl implements ViewParent, .unregisterDisplayListener(mDisplayListener); if (forceInvertColor()) { if (mForceInvertStateChangeListener != null) { mUiModeManager.removeForceInvertStateChangeListener( mForceInvertStateChangeListener); mForceInvertStateChangeListener = null; if (mForceInvertObserver != null) { mContext.getContentResolver().unregisterContentObserver(mForceInvertObserver); mForceInvertObserver = null; } } Loading Loading @@ -2047,25 +2072,21 @@ public final class ViewRootImpl implements ViewParent, return getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; } /** * Determines the type of force dark to apply, considering force inversion, system night mode, * and app-specific settings (including developer opt-outs). * * @return A {@link ForceDarkType.ForceDarkTypeDef} constant indicating the force dark type. */ /** Returns true if force dark should be enabled according to various settings */ @VisibleForTesting public @ForceDarkType.ForceDarkTypeDef int determineForceDarkType() { if (forceInvertColor()) { // Force invert ignores all developer opt-outs. // We also ignore dark theme, since the app developer can override the user's preference // for dark mode in configuration.uiMode. Instead, we assume that both force invert and // the system's dark theme are enabled. if (mUiModeManager.getForceInvertState() == UiModeManager.FORCE_INVERT_TYPE_DARK) { // for dark mode in configuration.uiMode. Instead, we assume that the force invert // setting will be enabled at the same time dark theme is in the Settings app. if (isForceInvertEnabled()) { return ForceDarkType.FORCE_INVERT_COLOR_DARK; } } boolean useAutoDark = getNightMode() == Configuration.UI_MODE_NIGHT_YES; if (useAutoDark) { boolean forceDarkAllowedDefault = SystemProperties.getBoolean(ThreadedRenderer.DEBUG_FORCE_DARK, false); Loading core/tests/coretests/src/android/view/ViewRootImplTest.java +44 −71 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package android.view; import static android.app.UiModeManager.MODE_NIGHT_NO; import static android.app.UiModeManager.MODE_NIGHT_YES; import static android.util.SequenceUtils.getInitSeq; import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING; import static android.view.InputDevice.SOURCE_ROTARY_ENCODER; Loading Loading @@ -69,10 +67,8 @@ import static org.junit.Assume.assumeTrue; import android.annotation.NonNull; import android.app.Instrumentation; import android.app.UiModeManager; import android.app.UiModeManager.ForceInvertType; import android.content.Context; import android.graphics.ForceDarkType; import android.graphics.ForceDarkType.ForceDarkTypeDef; import android.graphics.Rect; import android.hardware.display.DisplayManagerGlobal; import android.os.Binder; Loading @@ -97,12 +93,9 @@ import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.compatibility.common.util.ShellIdentityUtils; import com.android.compatibility.common.util.TestUtils; import com.android.cts.input.BlockingQueueEventVerifier; import com.android.window.flags.Flags; import com.google.common.truth.Expect; import org.hamcrest.Matcher; import org.junit.After; import org.junit.AfterClass; Loading Loading @@ -131,8 +124,6 @@ public class ViewRootImplTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule public final Expect mExpect = Expect.create(); private ViewRootImpl mViewRootImpl; private View mView; Loading Loading @@ -1516,34 +1507,49 @@ public class ViewRootImplTest { } @Test @RequiresFlagsEnabled(FLAG_FORCE_INVERT_COLOR) public void updateConfiguration_returnsExpectedForceDarkMode() { waitForSystemNightModeActivated(true); verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ true, UiModeManager.FORCE_INVERT_TYPE_DARK, ForceDarkType.FORCE_INVERT_COLOR_DARK); verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ false, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ true, UiModeManager.FORCE_INVERT_TYPE_DARK, ForceDarkType.FORCE_INVERT_COLOR_DARK); verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ false, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); waitForSystemNightModeActivated(false); verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ true, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ false, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ true, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ false, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); public void forceInvertOffDarkThemeOff_forceDarkModeDisabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); ShellIdentityUtils.invokeWithShellPermissions(() -> { Settings.Secure.putInt( sContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* value= */ 0 ); var uiModeManager = sContext.getSystemService(UiModeManager.class); uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO); }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()) ); assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.NONE); } @Test public void forceInvertOnDarkThemeOff_forceDarkModeEnabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); ShellIdentityUtils.invokeWithShellPermissions(() -> { Settings.Secure.putInt( sContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* value= */ 1 ); var uiModeManager = sContext.getSystemService(UiModeManager.class); uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO); }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()) ); assertThat(mViewRootImpl.determineForceDarkType()) .isEqualTo(ForceDarkType.FORCE_INVERT_COLOR_DARK); } @Test @EnableFlags(FLAG_FORCE_INVERT_COLOR) public void forceInvertOffForceDarkOff_forceDarkModeDisabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); ShellIdentityUtils.invokeWithShellPermissions(() -> { Settings.Secure.putInt( sContext.getContentResolver(), Loading @@ -1556,14 +1562,15 @@ public class ViewRootImplTest { }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())); mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()) ); assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.NONE); } @Test @EnableFlags(FLAG_FORCE_INVERT_COLOR) public void forceInvertOffForceDarkOn_forceDarkModeEnabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); ShellIdentityUtils.invokeWithShellPermissions(() -> { Settings.Secure.putInt( sContext.getContentResolver(), Loading @@ -1575,7 +1582,8 @@ public class ViewRootImplTest { }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())); mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()) ); assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.FORCE_DARK); } Loading Loading @@ -1782,39 +1790,4 @@ public class ViewRootImplTest { () -> view.getViewTreeObserver().removeOnDrawListener(listener)); } } private void waitForSystemNightModeActivated(boolean active) { ShellIdentityUtils.invokeWithShellPermissions(() -> sInstrumentation.runOnMainSync(() -> { var uiModeManager = sContext.getSystemService(UiModeManager.class); uiModeManager.setNightModeActivated(active); })); sInstrumentation.waitForIdleSync(); } private void verifyForceDarkType(boolean isAppInNightMode, boolean isForceInvertEnabled, @ForceInvertType int expectedForceInvertType, @ForceDarkTypeDef int expectedForceDarkType) { var uiModeManager = sContext.getSystemService(UiModeManager.class); ShellIdentityUtils.invokeWithShellPermissions(() -> { uiModeManager.setApplicationNightMode( isAppInNightMode ? MODE_NIGHT_YES : MODE_NIGHT_NO); Settings.Secure.putInt( sContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, isForceInvertEnabled ? 1 : 0); }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())); try { TestUtils.waitUntil("Waiting for force invert state changed", () -> (uiModeManager.getForceInvertState() == expectedForceInvertType)); } catch (Exception e) { Log.e(TAG, "Unexpected error trying to apply force invert state. " + e); e.printStackTrace(); } mExpect.that(mViewRootImpl.determineForceDarkType()).isEqualTo(expectedForceDarkType); } } Loading
core/java/android/view/ViewRootImpl.java +45 −24 Original line number Diff line number Diff line Loading @@ -152,8 +152,6 @@ import android.annotation.UiContext; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.ResourcesManager; import android.app.UiModeManager; import android.app.UiModeManager.ForceInvertStateChangeListener; import android.app.WindowConfiguration; import android.app.compat.CompatChanges; import android.app.servertransaction.WindowStateTransactionItem; Loading @@ -169,6 +167,7 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.database.ContentObserver; import android.graphics.BLASTBufferQueue; import android.graphics.Canvas; import android.graphics.Color; Loading Loading @@ -214,6 +213,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.os.Vibrator; import android.provider.Settings; import android.sysprop.DisplayProperties; import android.sysprop.ViewProperties; import android.text.TextUtils; Loading Loading @@ -469,8 +469,10 @@ public final class ViewRootImpl implements ViewParent, private CompatOnBackInvokedCallback mCompatOnBackInvokedCallback; @Nullable private ForceInvertStateChangeListener mForceInvertStateChangeListener; private ContentObserver mForceInvertObserver; private static final int INVALID_VALUE = Integer.MIN_VALUE; private int mForceInvertEnabled = INVALID_VALUE; /** * Callback for notifying about global configuration changes. */ Loading Loading @@ -552,8 +554,6 @@ public final class ViewRootImpl implements ViewParent, @UiContext public final Context mContext; private UiModeManager mUiModeManager; @UnsupportedAppUsage final IWindowSession mWindowSession; @NonNull Display mDisplay; Loading Loading @@ -1255,7 +1255,6 @@ public final class ViewRootImpl implements ViewParent, public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session, WindowLayout windowLayout) { mContext = context; mUiModeManager = context.getSystemService(UiModeManager.class); mWindowSession = session; mWindowLayout = windowLayout; mDisplay = display; Loading Loading @@ -1804,6 +1803,23 @@ public final class ViewRootImpl implements ViewParent, } } private boolean isForceInvertEnabled() { if (mForceInvertEnabled == INVALID_VALUE) { reloadForceInvertEnabled(); } return mForceInvertEnabled == 1; } private void reloadForceInvertEnabled() { if (forceInvertColor()) { mForceInvertEnabled = Settings.Secure.getIntForUser( mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* def= */ 0, UserHandle.myUserId()); } } /** * Register any kind of listeners if setView was success. */ Loading Loading @@ -1835,11 +1851,21 @@ public final class ViewRootImpl implements ViewParent, mBasePackageName); if (forceInvertColor()) { if (mForceInvertStateChangeListener == null) { mForceInvertStateChangeListener = forceInvertState -> updateForceDarkMode(); mUiModeManager.addForceInvertStateChangeListener(mExecutor, mForceInvertStateChangeListener); if (mForceInvertObserver == null) { mForceInvertObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { reloadForceInvertEnabled(); updateForceDarkMode(); } }; mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor( Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED ), false, mForceInvertObserver, UserHandle.myUserId()); } } } Loading @@ -1857,10 +1883,9 @@ public final class ViewRootImpl implements ViewParent, .unregisterDisplayListener(mDisplayListener); if (forceInvertColor()) { if (mForceInvertStateChangeListener != null) { mUiModeManager.removeForceInvertStateChangeListener( mForceInvertStateChangeListener); mForceInvertStateChangeListener = null; if (mForceInvertObserver != null) { mContext.getContentResolver().unregisterContentObserver(mForceInvertObserver); mForceInvertObserver = null; } } Loading Loading @@ -2047,25 +2072,21 @@ public final class ViewRootImpl implements ViewParent, return getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; } /** * Determines the type of force dark to apply, considering force inversion, system night mode, * and app-specific settings (including developer opt-outs). * * @return A {@link ForceDarkType.ForceDarkTypeDef} constant indicating the force dark type. */ /** Returns true if force dark should be enabled according to various settings */ @VisibleForTesting public @ForceDarkType.ForceDarkTypeDef int determineForceDarkType() { if (forceInvertColor()) { // Force invert ignores all developer opt-outs. // We also ignore dark theme, since the app developer can override the user's preference // for dark mode in configuration.uiMode. Instead, we assume that both force invert and // the system's dark theme are enabled. if (mUiModeManager.getForceInvertState() == UiModeManager.FORCE_INVERT_TYPE_DARK) { // for dark mode in configuration.uiMode. Instead, we assume that the force invert // setting will be enabled at the same time dark theme is in the Settings app. if (isForceInvertEnabled()) { return ForceDarkType.FORCE_INVERT_COLOR_DARK; } } boolean useAutoDark = getNightMode() == Configuration.UI_MODE_NIGHT_YES; if (useAutoDark) { boolean forceDarkAllowedDefault = SystemProperties.getBoolean(ThreadedRenderer.DEBUG_FORCE_DARK, false); Loading
core/tests/coretests/src/android/view/ViewRootImplTest.java +44 −71 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package android.view; import static android.app.UiModeManager.MODE_NIGHT_NO; import static android.app.UiModeManager.MODE_NIGHT_YES; import static android.util.SequenceUtils.getInitSeq; import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING; import static android.view.InputDevice.SOURCE_ROTARY_ENCODER; Loading Loading @@ -69,10 +67,8 @@ import static org.junit.Assume.assumeTrue; import android.annotation.NonNull; import android.app.Instrumentation; import android.app.UiModeManager; import android.app.UiModeManager.ForceInvertType; import android.content.Context; import android.graphics.ForceDarkType; import android.graphics.ForceDarkType.ForceDarkTypeDef; import android.graphics.Rect; import android.hardware.display.DisplayManagerGlobal; import android.os.Binder; Loading @@ -97,12 +93,9 @@ import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.compatibility.common.util.ShellIdentityUtils; import com.android.compatibility.common.util.TestUtils; import com.android.cts.input.BlockingQueueEventVerifier; import com.android.window.flags.Flags; import com.google.common.truth.Expect; import org.hamcrest.Matcher; import org.junit.After; import org.junit.AfterClass; Loading Loading @@ -131,8 +124,6 @@ public class ViewRootImplTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule public final Expect mExpect = Expect.create(); private ViewRootImpl mViewRootImpl; private View mView; Loading Loading @@ -1516,34 +1507,49 @@ public class ViewRootImplTest { } @Test @RequiresFlagsEnabled(FLAG_FORCE_INVERT_COLOR) public void updateConfiguration_returnsExpectedForceDarkMode() { waitForSystemNightModeActivated(true); verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ true, UiModeManager.FORCE_INVERT_TYPE_DARK, ForceDarkType.FORCE_INVERT_COLOR_DARK); verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ false, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ true, UiModeManager.FORCE_INVERT_TYPE_DARK, ForceDarkType.FORCE_INVERT_COLOR_DARK); verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ false, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); waitForSystemNightModeActivated(false); verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ true, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ false, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ true, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ false, UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE); public void forceInvertOffDarkThemeOff_forceDarkModeDisabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); ShellIdentityUtils.invokeWithShellPermissions(() -> { Settings.Secure.putInt( sContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* value= */ 0 ); var uiModeManager = sContext.getSystemService(UiModeManager.class); uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO); }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()) ); assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.NONE); } @Test public void forceInvertOnDarkThemeOff_forceDarkModeEnabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); ShellIdentityUtils.invokeWithShellPermissions(() -> { Settings.Secure.putInt( sContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* value= */ 1 ); var uiModeManager = sContext.getSystemService(UiModeManager.class); uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO); }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()) ); assertThat(mViewRootImpl.determineForceDarkType()) .isEqualTo(ForceDarkType.FORCE_INVERT_COLOR_DARK); } @Test @EnableFlags(FLAG_FORCE_INVERT_COLOR) public void forceInvertOffForceDarkOff_forceDarkModeDisabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); ShellIdentityUtils.invokeWithShellPermissions(() -> { Settings.Secure.putInt( sContext.getContentResolver(), Loading @@ -1556,14 +1562,15 @@ public class ViewRootImplTest { }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())); mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()) ); assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.NONE); } @Test @EnableFlags(FLAG_FORCE_INVERT_COLOR) public void forceInvertOffForceDarkOn_forceDarkModeEnabled() { mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR); ShellIdentityUtils.invokeWithShellPermissions(() -> { Settings.Secure.putInt( sContext.getContentResolver(), Loading @@ -1575,7 +1582,8 @@ public class ViewRootImplTest { }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())); mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()) ); assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.FORCE_DARK); } Loading Loading @@ -1782,39 +1790,4 @@ public class ViewRootImplTest { () -> view.getViewTreeObserver().removeOnDrawListener(listener)); } } private void waitForSystemNightModeActivated(boolean active) { ShellIdentityUtils.invokeWithShellPermissions(() -> sInstrumentation.runOnMainSync(() -> { var uiModeManager = sContext.getSystemService(UiModeManager.class); uiModeManager.setNightModeActivated(active); })); sInstrumentation.waitForIdleSync(); } private void verifyForceDarkType(boolean isAppInNightMode, boolean isForceInvertEnabled, @ForceInvertType int expectedForceInvertType, @ForceDarkTypeDef int expectedForceDarkType) { var uiModeManager = sContext.getSystemService(UiModeManager.class); ShellIdentityUtils.invokeWithShellPermissions(() -> { uiModeManager.setApplicationNightMode( isAppInNightMode ? MODE_NIGHT_YES : MODE_NIGHT_NO); Settings.Secure.putInt( sContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, isForceInvertEnabled ? 1 : 0); }); sInstrumentation.runOnMainSync(() -> mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())); try { TestUtils.waitUntil("Waiting for force invert state changed", () -> (uiModeManager.getForceInvertState() == expectedForceInvertType)); } catch (Exception e) { Log.e(TAG, "Unexpected error trying to apply force invert state. " + e); e.printStackTrace(); } mExpect.that(mViewRootImpl.determineForceDarkType()).isEqualTo(expectedForceDarkType); } }