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

Commit 97d9eebb authored by Chun-Ku Lin's avatar Chun-Ku Lin Committed by Android (Google) Code Review
Browse files

Merge "Handle restore on ACCESSIBILITY_QS_TARGETS setting" into main

parents 89d36feb 03e70fb7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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",
+5 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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
+37 −0
Original line number Diff line number Diff line
@@ -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
@@ -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);
    }
}
+29 −0
Original line number Diff line number Diff line
@@ -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));
                    }
                }
            }
@@ -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(),
+4 −0
Original line number Diff line number Diff line
@@ -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