Loading packages/SettingsProvider/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ android_test { // because this test is not an instrumentation test. (because the target runs in the system process.) "SettingsProviderLib", "androidx.test.rules", "frameworks-base-testutils", "device_config_service_flags_java", "flag-junit", "junit", Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +5 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class SettingsHelper { sBroadcastOnRestore.add(Settings.Secure.DARK_THEME_CUSTOM_END_TIME); sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED); sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); sBroadcastOnRestoreSystemUI = new ArraySet<String>(2); sBroadcastOnRestoreSystemUI.add(Settings.Secure.QS_TILES); sBroadcastOnRestoreSystemUI.add(Settings.Secure.QS_AUTO_ADDED_TILES); Loading Loading @@ -229,6 +230,10 @@ public class SettingsHelper { } else if (Settings.System.ACCELEROMETER_ROTATION.equals(name) && shouldSkipAutoRotateRestore()) { return; } else if (Settings.Secure.ACCESSIBILITY_QS_TARGETS.equals(name)) { // Don't write it to setting. Let the broadcast receiver in // AccessibilityManagerService handle restore/merging logic. return; } // Default case: write the restored value to settings Loading packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java +37 −0 Original line number Diff line number Diff line Loading @@ -16,23 +16,31 @@ package com.android.providers.settings; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.provider.Settings; import android.provider.SettingsStringUtil; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.test.BroadcastInterceptingContext; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import java.util.concurrent.ExecutionException; /** * Tests for {@link SettingsHelper#restoreValue(Context, ContentResolver, ContentValues, Uri, * String, String, int)}. Specifically verifies that we restore critical accessibility settings only Loading Loading @@ -165,4 +173,33 @@ public class SettingsHelperRestoreTest { assertEquals(restoreSettingValue, Settings.Secure.getInt(mContentResolver, settingName)); } @Test public void restoreAccessibilityQsTargets_broadcastSent() throws ExecutionException, InterruptedException { BroadcastInterceptingContext interceptingContext = new BroadcastInterceptingContext( mContext); final String settingName = Settings.Secure.ACCESSIBILITY_QS_TARGETS; final String restoreSettingValue = "com.android.server.accessibility/ColorInversion" + SettingsStringUtil.DELIMITER + "com.android.server.accessibility/ColorCorrectionTile"; BroadcastInterceptingContext.FutureIntent futureIntent = interceptingContext.nextBroadcastIntent(Intent.ACTION_SETTING_RESTORED); mSettingsHelper.restoreValue( interceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), settingName, restoreSettingValue, Build.VERSION.SDK_INT); Intent intentReceived = futureIntent.get(); assertThat(intentReceived.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)) .isEqualTo(restoreSettingValue); assertThat(intentReceived.getIntExtra( Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, /* defaultValue= */ 0)) .isEqualTo(Build.VERSION.SDK_INT); } } services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +29 −0 Original line number Diff line number Diff line Loading @@ -993,6 +993,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE), intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)); } } else if (Settings.Secure.ACCESSIBILITY_QS_TARGETS.equals(which)) { if (!android.view.accessibility.Flags.a11yQsShortcut()) { return; } restoreAccessibilityQsTargets( intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)); } } } Loading Loading @@ -2131,6 +2137,29 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub onUserStateChangedLocked(userState); } /** * User could configure accessibility shortcut during the SUW before restoring user data. * Merges the current value and the new value to make sure we don't lost the setting the user's * preferences of accessibility qs shortcut updated in SUW are not lost. * * Called only during settings restore; currently supports only the owner user * TODO: http://b/22388012 */ private void restoreAccessibilityQsTargets(String newValue) { synchronized (mLock) { final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM); final Set<String> mergedTargets = userState.getA11yQsTargets(); readColonDelimitedStringToSet(newValue, str -> str, mergedTargets, /* doMerge = */ true); userState.updateA11yQsTargetLocked(mergedTargets); persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_QS_TARGETS, UserHandle.USER_SYSTEM, mergedTargets, str -> str); scheduleNotifyClientsOfServicesStateChangeLocked(userState); onUserStateChangedLocked(userState); } } private int getClientStateLocked(AccessibilityUserState userState) { return userState.getClientStateLocked( mUiAutomationManager.canIntrospect(), Loading services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java +4 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,10 @@ class AccessibilityUserState { * TileService's or the a11y framework tile component names (e.g. * {@link AccessibilityShortcutController#COLOR_INVERSION_TILE_COMPONENT_NAME}) instead of the * A11y Feature's component names. * <p/> * In addition, {@link #mA11yTilesInQsPanel} stores what's on the QS Panel, whereas * {@link #mAccessibilityQsTargets} stores the targets that configured qs as their shortcut and * also grant full device control permission. */ private final ArraySet<ComponentName> mA11yTilesInQsPanel = new ArraySet<>(); Loading Loading
packages/SettingsProvider/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ android_test { // because this test is not an instrumentation test. (because the target runs in the system process.) "SettingsProviderLib", "androidx.test.rules", "frameworks-base-testutils", "device_config_service_flags_java", "flag-junit", "junit", Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +5 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class SettingsHelper { sBroadcastOnRestore.add(Settings.Secure.DARK_THEME_CUSTOM_END_TIME); sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED); sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS); sBroadcastOnRestore.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS); sBroadcastOnRestoreSystemUI = new ArraySet<String>(2); sBroadcastOnRestoreSystemUI.add(Settings.Secure.QS_TILES); sBroadcastOnRestoreSystemUI.add(Settings.Secure.QS_AUTO_ADDED_TILES); Loading Loading @@ -229,6 +230,10 @@ public class SettingsHelper { } else if (Settings.System.ACCELEROMETER_ROTATION.equals(name) && shouldSkipAutoRotateRestore()) { return; } else if (Settings.Secure.ACCESSIBILITY_QS_TARGETS.equals(name)) { // Don't write it to setting. Let the broadcast receiver in // AccessibilityManagerService handle restore/merging logic. return; } // Default case: write the restored value to settings Loading
packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java +37 −0 Original line number Diff line number Diff line Loading @@ -16,23 +16,31 @@ package com.android.providers.settings; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.provider.Settings; import android.provider.SettingsStringUtil; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.test.BroadcastInterceptingContext; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import java.util.concurrent.ExecutionException; /** * Tests for {@link SettingsHelper#restoreValue(Context, ContentResolver, ContentValues, Uri, * String, String, int)}. Specifically verifies that we restore critical accessibility settings only Loading Loading @@ -165,4 +173,33 @@ public class SettingsHelperRestoreTest { assertEquals(restoreSettingValue, Settings.Secure.getInt(mContentResolver, settingName)); } @Test public void restoreAccessibilityQsTargets_broadcastSent() throws ExecutionException, InterruptedException { BroadcastInterceptingContext interceptingContext = new BroadcastInterceptingContext( mContext); final String settingName = Settings.Secure.ACCESSIBILITY_QS_TARGETS; final String restoreSettingValue = "com.android.server.accessibility/ColorInversion" + SettingsStringUtil.DELIMITER + "com.android.server.accessibility/ColorCorrectionTile"; BroadcastInterceptingContext.FutureIntent futureIntent = interceptingContext.nextBroadcastIntent(Intent.ACTION_SETTING_RESTORED); mSettingsHelper.restoreValue( interceptingContext, mContentResolver, new ContentValues(2), Settings.Secure.getUriFor(settingName), settingName, restoreSettingValue, Build.VERSION.SDK_INT); Intent intentReceived = futureIntent.get(); assertThat(intentReceived.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)) .isEqualTo(restoreSettingValue); assertThat(intentReceived.getIntExtra( Intent.EXTRA_SETTING_RESTORED_FROM_SDK_INT, /* defaultValue= */ 0)) .isEqualTo(Build.VERSION.SDK_INT); } }
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +29 −0 Original line number Diff line number Diff line Loading @@ -993,6 +993,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE), intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)); } } else if (Settings.Secure.ACCESSIBILITY_QS_TARGETS.equals(which)) { if (!android.view.accessibility.Flags.a11yQsShortcut()) { return; } restoreAccessibilityQsTargets( intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE)); } } } Loading Loading @@ -2131,6 +2137,29 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub onUserStateChangedLocked(userState); } /** * User could configure accessibility shortcut during the SUW before restoring user data. * Merges the current value and the new value to make sure we don't lost the setting the user's * preferences of accessibility qs shortcut updated in SUW are not lost. * * Called only during settings restore; currently supports only the owner user * TODO: http://b/22388012 */ private void restoreAccessibilityQsTargets(String newValue) { synchronized (mLock) { final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM); final Set<String> mergedTargets = userState.getA11yQsTargets(); readColonDelimitedStringToSet(newValue, str -> str, mergedTargets, /* doMerge = */ true); userState.updateA11yQsTargetLocked(mergedTargets); persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_QS_TARGETS, UserHandle.USER_SYSTEM, mergedTargets, str -> str); scheduleNotifyClientsOfServicesStateChangeLocked(userState); onUserStateChangedLocked(userState); } } private int getClientStateLocked(AccessibilityUserState userState) { return userState.getClientStateLocked( mUiAutomationManager.canIntrospect(), Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java +4 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,10 @@ class AccessibilityUserState { * TileService's or the a11y framework tile component names (e.g. * {@link AccessibilityShortcutController#COLOR_INVERSION_TILE_COMPONENT_NAME}) instead of the * A11y Feature's component names. * <p/> * In addition, {@link #mA11yTilesInQsPanel} stores what's on the QS Panel, whereas * {@link #mAccessibilityQsTargets} stores the targets that configured qs as their shortcut and * also grant full device control permission. */ private final ArraySet<ComponentName> mA11yTilesInQsPanel = new ArraySet<>(); Loading