Loading Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ android_library { ], srcs: [ "tests/tapl/**/*.java", "src/com/android/launcher3/util/SecureSettingsObserver.java", "src/com/android/launcher3/ResourceUtils.java", "src/com/android/launcher3/testing/TestProtocol.java", ], Loading quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +26 −23 Original line number Diff line number Diff line Loading @@ -17,14 +17,16 @@ package com.android.quickstep; import static android.content.Intent.ACTION_USER_UNLOCKED; import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED; import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED; import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ALL; import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_FRAME_DELAY; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED; Loading @@ -44,6 +46,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.graphics.Region; import android.net.Uri; import android.os.Process; import android.os.SystemProperties; import android.os.UserManager; Loading @@ -57,11 +60,11 @@ import androidx.annotation.BinderThread; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.SettingsCache; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.DisplayHolder; import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.SecureSettingsObserver; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; import com.android.quickstep.SysUINavigationMode.OneHandedModeChangeListener; import com.android.quickstep.util.NavBarPosition; Loading Loading @@ -177,33 +180,33 @@ public class RecentsAnimationDeviceState implements } } SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext); if (mIsOneHandedModeSupported) { SecureSettingsObserver oneHandedEnabledObserver = SecureSettingsObserver.newOneHandedSettingsObserver( mContext, enabled -> mIsOneHandedModeEnabled = enabled); oneHandedEnabledObserver.register(); oneHandedEnabledObserver.dispatchOnChange(); runOnDestroy(oneHandedEnabledObserver::unregister); Uri oneHandedUri = Settings.Secure.getUriFor(ONE_HANDED_ENABLED); SettingsCache.OnChangeListener onChangeListener = enabled -> mIsOneHandedModeEnabled = enabled; settingsCache.register(oneHandedUri, onChangeListener); settingsCache.dispatchOnChange(oneHandedUri); runOnDestroy(() -> settingsCache.unregister(oneHandedUri, onChangeListener)); } else { mIsOneHandedModeEnabled = false; } SecureSettingsObserver swipeBottomEnabledObserver = SecureSettingsObserver.newSwipeToNotificationSettingsObserver( mContext, enabled -> mIsSwipeToNotificationEnabled = enabled); swipeBottomEnabledObserver.register(); swipeBottomEnabledObserver.dispatchOnChange(); runOnDestroy(swipeBottomEnabledObserver::unregister); SecureSettingsObserver userSetupObserver = new SecureSettingsObserver( context.getContentResolver(), e -> mIsUserSetupComplete = e, Settings.Secure.USER_SETUP_COMPLETE, 0); mIsUserSetupComplete = userSetupObserver.getValue(); Uri swipeBottomNotificationUri = Settings.Secure.getUriFor(ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED); SettingsCache.OnChangeListener onChangeListener = enabled -> mIsSwipeToNotificationEnabled = enabled; settingsCache.register(swipeBottomNotificationUri, onChangeListener); settingsCache.dispatchOnChange(swipeBottomNotificationUri); runOnDestroy(() -> settingsCache.unregister(swipeBottomNotificationUri, onChangeListener)); Uri setupCompleteUri = Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE); mIsUserSetupComplete = settingsCache.getValue(setupCompleteUri, 0); if (!mIsUserSetupComplete) { userSetupObserver.register(); runOnDestroy(userSetupObserver::unregister); SettingsCache.OnChangeListener userSetupChangeListener = e -> mIsUserSetupComplete = e; settingsCache.register(setupCompleteUri, userSetupChangeListener); runOnDestroy(() -> settingsCache.unregister(setupCompleteUri, userSetupChangeListener)); } } Loading quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java +6 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_DISABLED; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_ENABLED; import static com.android.launcher3.model.QuickstepModelDelegate.LAST_PREDICTION_ENABLED_STATE; import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver; import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI; import android.content.Context; import android.content.SharedPreferences; Loading @@ -43,7 +43,7 @@ import com.android.launcher3.R; import com.android.launcher3.logging.InstanceIdSequence; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.util.SecureSettingsObserver; import com.android.launcher3.util.SettingsCache; import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; Loading Loading @@ -77,11 +77,10 @@ public class SettingsChangeLogger implements getPrefs(context).registerOnSharedPreferenceChangeListener(this); getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this); SecureSettingsObserver dotsObserver = newNotificationSettingsObserver(context, this::onNotificationDotsChanged); mNotificationDotsEnabled = dotsObserver.getValue(); dispatchUserEvent(); SettingsCache mSettingsCache = SettingsCache.INSTANCE.get(context); mSettingsCache.register(NOTIFICATION_BADGING_URI, this::onNotificationDotsChanged); mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI); } private static ArrayMap<String, LoggablePref> loadPrefKeys(Context context) { Loading quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +10 −16 Original line number Diff line number Diff line Loading @@ -23,22 +23,18 @@ import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static com.android.launcher3.Utilities.newContentObserver; import static com.android.launcher3.util.SettingsCache.ROTATION_SETTING_URI; import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.Rect; import android.os.Handler; import android.provider.Settings; import android.util.Log; import android.view.MotionEvent; import android.view.OrientationEventListener; Loading @@ -51,6 +47,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.SettingsCache; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.WindowBounds; Loading @@ -72,9 +69,6 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre private static final String TAG = "RecentsOrientedState"; private static final boolean DEBUG = false; private ContentObserver mSystemAutoRotateObserver = newContentObserver(new Handler(), t -> updateAutoRotateSetting()); @Retention(SOURCE) @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) public @interface SurfaceRotation {} Loading Loading @@ -118,9 +112,11 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre | FLAG_SWIPE_UP_NOT_RUNNING; private final Context mContext; private final ContentResolver mContentResolver; private final SharedPreferences mSharedPrefs; private final OrientationEventListener mOrientationListener; private final SettingsCache mSettingsCache; private final SettingsCache.OnChangeListener mRotationChangeListener = isEnabled -> updateAutoRotateSetting(); private final Matrix mTmpMatrix = new Matrix(); Loading @@ -138,7 +134,6 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre public RecentsOrientedState(Context context, BaseActivityInterface sizeStrategy, IntConsumer rotationChangeListener) { mContext = context; mContentResolver = context.getContentResolver(); mSharedPrefs = Utilities.getPrefs(context); mOrientationListener = new OrientationEventListener(context) { @Override Loading @@ -162,6 +157,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY; } mFlags |= FLAG_SWIPE_UP_NOT_RUNNING; mSettingsCache = SettingsCache.INSTANCE.get(mContext); initFlags(); } Loading Loading @@ -271,8 +267,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre } private void updateAutoRotateSetting() { setFlag(FLAG_SYSTEM_ROTATION_ALLOWED, Settings.System.getInt(mContentResolver, Settings.System.ACCELEROMETER_ROTATION, 1) == 1); setFlag(FLAG_SYSTEM_ROTATION_ALLOWED, mSettingsCache.getValue(ROTATION_SETTING_URI, 1)); } private void updateHomeRotationSetting() { Loading @@ -295,9 +291,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre public void initListeners() { if (isMultipleOrientationSupportedByDevice()) { mSharedPrefs.registerOnSharedPreferenceChangeListener(this); mContentResolver.registerContentObserver( Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), false, mSystemAutoRotateObserver); mSettingsCache.register(ROTATION_SETTING_URI, mRotationChangeListener); } initFlags(); } Loading @@ -308,7 +302,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre public void destroyListeners() { if (isMultipleOrientationSupportedByDevice()) { mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this); mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver); mSettingsCache.unregister(ROTATION_SETTING_URI, mRotationChangeListener); } setRotationWatcherEnabled(false); } Loading robolectric_tests/src/com/android/launcher3/util/SettingsCacheTest.java 0 → 100644 +115 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.util; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.Context; import android.net.Uri; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.Collections; @RunWith(RobolectricTestRunner.class) public class SettingsCacheTest { public static final Uri KEY_SYSTEM_URI_TEST1 = Uri.parse("content://settings/system/test1"); public static final Uri KEY_SYSTEM_URI_TEST2 = Uri.parse("content://settings/system/test2");; private SettingsCache.OnChangeListener mChangeListener; private SettingsCache mSettingsCache; @Before public void setup() { mChangeListener = mock(SettingsCache.OnChangeListener.class); Context targetContext = RuntimeEnvironment.application; mSettingsCache = SettingsCache.INSTANCE.get(targetContext); mSettingsCache.register(KEY_SYSTEM_URI_TEST1, mChangeListener); } @Test public void listenerCalledOnChange() { mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1); verify(mChangeListener, times(1)).onSettingsChanged(true); } @Test public void getValueRespectsDefaultValue() { // Case of key not found boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0); assertFalse(val); } @Test public void getValueHitsCache() { mSettingsCache.setKeyCache(Collections.singletonMap(KEY_SYSTEM_URI_TEST1, true)); boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0); assertTrue(val); } @Test public void getValueUpdatedCache() { // First ensure there's nothing in cache boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0); assertFalse(val); mSettingsCache.setKeyCache(Collections.singletonMap(KEY_SYSTEM_URI_TEST1, true)); val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0); assertTrue(val); } @Test public void multipleListenersSingleKey() { SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class); mSettingsCache.register(KEY_SYSTEM_URI_TEST1, secondListener); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1); verify(mChangeListener, times(1)).onSettingsChanged(true); verify(secondListener, times(1)).onSettingsChanged(true); } @Test public void singleListenerMultipleKeys() { SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class); mSettingsCache.register(KEY_SYSTEM_URI_TEST2, secondListener); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST2); verify(mChangeListener, times(1)).onSettingsChanged(true); verify(secondListener, times(1)).onSettingsChanged(true); } @Test public void sameListenerMultipleKeys() { SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class); mSettingsCache.register(KEY_SYSTEM_URI_TEST2, mChangeListener); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST2); verify(mChangeListener, times(2)).onSettingsChanged(true); verify(secondListener, times(0)).onSettingsChanged(true); } } Loading
Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ android_library { ], srcs: [ "tests/tapl/**/*.java", "src/com/android/launcher3/util/SecureSettingsObserver.java", "src/com/android/launcher3/ResourceUtils.java", "src/com/android/launcher3/testing/TestProtocol.java", ], Loading
quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +26 −23 Original line number Diff line number Diff line Loading @@ -17,14 +17,16 @@ package com.android.quickstep; import static android.content.Intent.ACTION_USER_UNLOCKED; import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED; import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED; import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ALL; import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_FRAME_DELAY; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED; Loading @@ -44,6 +46,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.graphics.Region; import android.net.Uri; import android.os.Process; import android.os.SystemProperties; import android.os.UserManager; Loading @@ -57,11 +60,11 @@ import androidx.annotation.BinderThread; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.SettingsCache; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.DisplayHolder; import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.SecureSettingsObserver; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; import com.android.quickstep.SysUINavigationMode.OneHandedModeChangeListener; import com.android.quickstep.util.NavBarPosition; Loading Loading @@ -177,33 +180,33 @@ public class RecentsAnimationDeviceState implements } } SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext); if (mIsOneHandedModeSupported) { SecureSettingsObserver oneHandedEnabledObserver = SecureSettingsObserver.newOneHandedSettingsObserver( mContext, enabled -> mIsOneHandedModeEnabled = enabled); oneHandedEnabledObserver.register(); oneHandedEnabledObserver.dispatchOnChange(); runOnDestroy(oneHandedEnabledObserver::unregister); Uri oneHandedUri = Settings.Secure.getUriFor(ONE_HANDED_ENABLED); SettingsCache.OnChangeListener onChangeListener = enabled -> mIsOneHandedModeEnabled = enabled; settingsCache.register(oneHandedUri, onChangeListener); settingsCache.dispatchOnChange(oneHandedUri); runOnDestroy(() -> settingsCache.unregister(oneHandedUri, onChangeListener)); } else { mIsOneHandedModeEnabled = false; } SecureSettingsObserver swipeBottomEnabledObserver = SecureSettingsObserver.newSwipeToNotificationSettingsObserver( mContext, enabled -> mIsSwipeToNotificationEnabled = enabled); swipeBottomEnabledObserver.register(); swipeBottomEnabledObserver.dispatchOnChange(); runOnDestroy(swipeBottomEnabledObserver::unregister); SecureSettingsObserver userSetupObserver = new SecureSettingsObserver( context.getContentResolver(), e -> mIsUserSetupComplete = e, Settings.Secure.USER_SETUP_COMPLETE, 0); mIsUserSetupComplete = userSetupObserver.getValue(); Uri swipeBottomNotificationUri = Settings.Secure.getUriFor(ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED); SettingsCache.OnChangeListener onChangeListener = enabled -> mIsSwipeToNotificationEnabled = enabled; settingsCache.register(swipeBottomNotificationUri, onChangeListener); settingsCache.dispatchOnChange(swipeBottomNotificationUri); runOnDestroy(() -> settingsCache.unregister(swipeBottomNotificationUri, onChangeListener)); Uri setupCompleteUri = Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE); mIsUserSetupComplete = settingsCache.getValue(setupCompleteUri, 0); if (!mIsUserSetupComplete) { userSetupObserver.register(); runOnDestroy(userSetupObserver::unregister); SettingsCache.OnChangeListener userSetupChangeListener = e -> mIsUserSetupComplete = e; settingsCache.register(setupCompleteUri, userSetupChangeListener); runOnDestroy(() -> settingsCache.unregister(setupCompleteUri, userSetupChangeListener)); } } Loading
quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java +6 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_DISABLED; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_ENABLED; import static com.android.launcher3.model.QuickstepModelDelegate.LAST_PREDICTION_ENABLED_STATE; import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver; import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI; import android.content.Context; import android.content.SharedPreferences; Loading @@ -43,7 +43,7 @@ import com.android.launcher3.R; import com.android.launcher3.logging.InstanceIdSequence; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.util.SecureSettingsObserver; import com.android.launcher3.util.SettingsCache; import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; Loading Loading @@ -77,11 +77,10 @@ public class SettingsChangeLogger implements getPrefs(context).registerOnSharedPreferenceChangeListener(this); getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this); SecureSettingsObserver dotsObserver = newNotificationSettingsObserver(context, this::onNotificationDotsChanged); mNotificationDotsEnabled = dotsObserver.getValue(); dispatchUserEvent(); SettingsCache mSettingsCache = SettingsCache.INSTANCE.get(context); mSettingsCache.register(NOTIFICATION_BADGING_URI, this::onNotificationDotsChanged); mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI); } private static ArrayMap<String, LoggablePref> loadPrefKeys(Context context) { Loading
quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +10 −16 Original line number Diff line number Diff line Loading @@ -23,22 +23,18 @@ import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static com.android.launcher3.Utilities.newContentObserver; import static com.android.launcher3.util.SettingsCache.ROTATION_SETTING_URI; import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.Rect; import android.os.Handler; import android.provider.Settings; import android.util.Log; import android.view.MotionEvent; import android.view.OrientationEventListener; Loading @@ -51,6 +47,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.SettingsCache; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.WindowBounds; Loading @@ -72,9 +69,6 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre private static final String TAG = "RecentsOrientedState"; private static final boolean DEBUG = false; private ContentObserver mSystemAutoRotateObserver = newContentObserver(new Handler(), t -> updateAutoRotateSetting()); @Retention(SOURCE) @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) public @interface SurfaceRotation {} Loading Loading @@ -118,9 +112,11 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre | FLAG_SWIPE_UP_NOT_RUNNING; private final Context mContext; private final ContentResolver mContentResolver; private final SharedPreferences mSharedPrefs; private final OrientationEventListener mOrientationListener; private final SettingsCache mSettingsCache; private final SettingsCache.OnChangeListener mRotationChangeListener = isEnabled -> updateAutoRotateSetting(); private final Matrix mTmpMatrix = new Matrix(); Loading @@ -138,7 +134,6 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre public RecentsOrientedState(Context context, BaseActivityInterface sizeStrategy, IntConsumer rotationChangeListener) { mContext = context; mContentResolver = context.getContentResolver(); mSharedPrefs = Utilities.getPrefs(context); mOrientationListener = new OrientationEventListener(context) { @Override Loading @@ -162,6 +157,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY; } mFlags |= FLAG_SWIPE_UP_NOT_RUNNING; mSettingsCache = SettingsCache.INSTANCE.get(mContext); initFlags(); } Loading Loading @@ -271,8 +267,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre } private void updateAutoRotateSetting() { setFlag(FLAG_SYSTEM_ROTATION_ALLOWED, Settings.System.getInt(mContentResolver, Settings.System.ACCELEROMETER_ROTATION, 1) == 1); setFlag(FLAG_SYSTEM_ROTATION_ALLOWED, mSettingsCache.getValue(ROTATION_SETTING_URI, 1)); } private void updateHomeRotationSetting() { Loading @@ -295,9 +291,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre public void initListeners() { if (isMultipleOrientationSupportedByDevice()) { mSharedPrefs.registerOnSharedPreferenceChangeListener(this); mContentResolver.registerContentObserver( Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), false, mSystemAutoRotateObserver); mSettingsCache.register(ROTATION_SETTING_URI, mRotationChangeListener); } initFlags(); } Loading @@ -308,7 +302,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre public void destroyListeners() { if (isMultipleOrientationSupportedByDevice()) { mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this); mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver); mSettingsCache.unregister(ROTATION_SETTING_URI, mRotationChangeListener); } setRotationWatcherEnabled(false); } Loading
robolectric_tests/src/com/android/launcher3/util/SettingsCacheTest.java 0 → 100644 +115 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.util; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.Context; import android.net.Uri; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.Collections; @RunWith(RobolectricTestRunner.class) public class SettingsCacheTest { public static final Uri KEY_SYSTEM_URI_TEST1 = Uri.parse("content://settings/system/test1"); public static final Uri KEY_SYSTEM_URI_TEST2 = Uri.parse("content://settings/system/test2");; private SettingsCache.OnChangeListener mChangeListener; private SettingsCache mSettingsCache; @Before public void setup() { mChangeListener = mock(SettingsCache.OnChangeListener.class); Context targetContext = RuntimeEnvironment.application; mSettingsCache = SettingsCache.INSTANCE.get(targetContext); mSettingsCache.register(KEY_SYSTEM_URI_TEST1, mChangeListener); } @Test public void listenerCalledOnChange() { mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1); verify(mChangeListener, times(1)).onSettingsChanged(true); } @Test public void getValueRespectsDefaultValue() { // Case of key not found boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0); assertFalse(val); } @Test public void getValueHitsCache() { mSettingsCache.setKeyCache(Collections.singletonMap(KEY_SYSTEM_URI_TEST1, true)); boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0); assertTrue(val); } @Test public void getValueUpdatedCache() { // First ensure there's nothing in cache boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0); assertFalse(val); mSettingsCache.setKeyCache(Collections.singletonMap(KEY_SYSTEM_URI_TEST1, true)); val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0); assertTrue(val); } @Test public void multipleListenersSingleKey() { SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class); mSettingsCache.register(KEY_SYSTEM_URI_TEST1, secondListener); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1); verify(mChangeListener, times(1)).onSettingsChanged(true); verify(secondListener, times(1)).onSettingsChanged(true); } @Test public void singleListenerMultipleKeys() { SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class); mSettingsCache.register(KEY_SYSTEM_URI_TEST2, secondListener); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST2); verify(mChangeListener, times(1)).onSettingsChanged(true); verify(secondListener, times(1)).onSettingsChanged(true); } @Test public void sameListenerMultipleKeys() { SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class); mSettingsCache.register(KEY_SYSTEM_URI_TEST2, mChangeListener); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1); mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST2); verify(mChangeListener, times(2)).onSettingsChanged(true); verify(secondListener, times(0)).onSettingsChanged(true); } }