Refactor SettingsContentObserver and add it to follow typing feature.
Refactor SettingsContentObserver and rename it to
AccessibilitySettingsContentObserver. Besides, we register it to observe
follow typing feature preference value.
The reasons behind refactor:
1. We change callback signature due to the consistency for register it
by preference key, not by Uri.
2. We refactor the default preference key to a seperate method. Since
the default value is related to accessibility, we rename it with
accessibility prefix.
3. We can register different callback for difference collections of
preference keys.
Default preference keys: They existed in the previous constructor.
1. Settings.Secure.ACCESSIBILITY_ENABLED
2. Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
Bug: 194668976
Test: make RunSettingsRoboTests ROBOTEST_FILTER=
AccessibilitySettingsTest
AccessibilitySettingsContentObserverTest
AccessibilityShortcutPreferenceFragmentTest
MagnificationFollowTypingPreferenceControllerTest
ToggleFeaturePreferenceFragmentTest
ToggleScreenMagnificationPreferenceFragmentTest
Change-Id: Iafd27e044ebe2536ae7ae55c1c80af54f7f0f822
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 8e8c7e4..c08e669 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -30,7 +30,6 @@
import android.content.pm.ServiceInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
-import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
@@ -147,7 +146,7 @@
};
@VisibleForTesting
- final SettingsContentObserver mSettingsContentObserver;
+ final AccessibilitySettingsContentObserver mSettingsContentObserver;
private final Map<String, PreferenceCategory> mCategoryToPrefCategoryMap =
new ArrayMap<>();
@@ -171,12 +170,9 @@
// Observe changes from accessibility selection menu
shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
- mSettingsContentObserver = new SettingsContentObserver(mHandler, shortcutFeatureKeys) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- onContentChanged();
- }
- };
+ mSettingsContentObserver = new AccessibilitySettingsContentObserver(mHandler);
+ mSettingsContentObserver.registerKeysToObserverCallback(shortcutFeatureKeys,
+ key -> onContentChanged());
}
@Override
diff --git a/src/com/android/settings/accessibility/AccessibilitySettingsContentObserver.java b/src/com/android/settings/accessibility/AccessibilitySettingsContentObserver.java
new file mode 100644
index 0000000..d2ca754
--- /dev/null
+++ b/src/com/android/settings/accessibility/AccessibilitySettingsContentObserver.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 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.settings.accessibility;
+
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class AccessibilitySettingsContentObserver extends ContentObserver {
+
+ private static final String TAG = "AccessibilitySettingsContentObserver";
+
+ public interface ContentObserverCallback {
+ void onChange(String key);
+ }
+
+ // Key: Preference key's uri, Value: Preference key
+ private final Map<Uri, String> mUriToKey = new HashMap<>(2);
+
+ // Key: Collection of preference keys, Value: onChange callback for keys
+ private final Map<List<String>, ContentObserverCallback> mUrisToCallback = new HashMap<>();
+
+ AccessibilitySettingsContentObserver(Handler handler) {
+ super(handler);
+
+ // default key to be observed
+ addDefaultKeysToMap();
+ }
+
+ public void register(ContentResolver contentResolver) {
+ for (Uri uri : mUriToKey.keySet()) {
+ contentResolver.registerContentObserver(uri, false, this);
+ }
+ }
+
+ public void unregister(ContentResolver contentResolver) {
+ contentResolver.unregisterContentObserver(this);
+ }
+
+ private void addDefaultKeysToMap() {
+ addKeyToMap(Settings.Secure.ACCESSIBILITY_ENABLED);
+ addKeyToMap(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ }
+
+ private boolean isDefaultKey(String key) {
+ return Settings.Secure.ACCESSIBILITY_ENABLED.equals(key)
+ || Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES.equals(key);
+ }
+
+ private void addKeyToMap(String key) {
+ mUriToKey.put(Settings.Secure.getUriFor(key), key);
+ }
+
+ /**
+ * {@link ContentObserverCallback} is added to {@link ContentObserver} to handle the
+ * onChange event triggered by the key collection of {@code keysToObserve} and the default
+ * keys.
+ *
+ * Note: The following key are default to be observed.
+ * {@link Settings.Secure.ACCESSIBILITY_ENABLED}
+ * {@link Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES}
+ *
+ * @param keysToObserve A collection of keys which are going to be observed.
+ * @param observerCallback A callback which is used to handle the onChange event triggered
+ * by the key collection of {@code keysToObserve}.
+ */
+ public void registerKeysToObserverCallback(List<String> keysToObserve,
+ ContentObserverCallback observerCallback) {
+
+ for (String key: keysToObserve) {
+ addKeyToMap(key);
+ }
+
+ mUrisToCallback.put(keysToObserve, observerCallback);
+ }
+
+ /**
+ * {@link ContentObserverCallback} is added to {@link ContentObserver} to handle the
+ * onChange event triggered by the default keys.
+ *
+ * Note: The following key are default to be observed.
+ * {@link Settings.Secure.ACCESSIBILITY_ENABLED}
+ * {@link Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES}
+ *
+ * @param observerCallback A callback which is used to handle the onChange event triggered
+ * * by the key collection of {@code keysToObserve}.
+ */
+ public void registerObserverCallback(ContentObserverCallback observerCallback) {
+ mUrisToCallback.put(Collections.emptyList(), observerCallback);
+ }
+
+ @Override
+ public final void onChange(boolean selfChange, Uri uri) {
+
+ final String key = mUriToKey.get(uri);
+
+ if (key == null) {
+ Log.w(TAG, "AccessibilitySettingsContentObserver can not find the key for "
+ + "uri: " + uri);
+ return;
+ }
+
+ for (List<String> keys : mUrisToCallback.keySet()) {
+ final boolean isDefaultKey = isDefaultKey(key);
+ if (isDefaultKey || keys.contains(key)) {
+ mUrisToCallback.get(keys).onChange(key);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index 22f037b..115f44f 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -25,7 +25,6 @@
import android.content.Context;
import android.content.DialogInterface;
import android.icu.text.CaseMap;
-import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
@@ -64,7 +63,7 @@
protected ShortcutPreference mShortcutPreference;
private AccessibilityManager.TouchExplorationStateChangeListener
mTouchExplorationStateChangeListener;
- private SettingsContentObserver mSettingsContentObserver;
+ private AccessibilitySettingsContentObserver mSettingsContentObserver;
private CheckBox mSoftwareTypeCheckBox;
private CheckBox mHardwareTypeCheckBox;
@@ -98,13 +97,11 @@
final List<String> shortcutFeatureKeys = new ArrayList<>();
shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
- mSettingsContentObserver = new SettingsContentObserver(new Handler(), shortcutFeatureKeys) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateShortcutPreferenceData();
- updateShortcutPreference();
- }
- };
+ mSettingsContentObserver = new AccessibilitySettingsContentObserver(new Handler());
+ mSettingsContentObserver.registerKeysToObserverCallback(shortcutFeatureKeys, key -> {
+ updateShortcutPreferenceData();
+ updateShortcutPreference();
+ });
}
@Override
diff --git a/src/com/android/settings/accessibility/MagnificationFollowTypingPreferenceController.java b/src/com/android/settings/accessibility/MagnificationFollowTypingPreferenceController.java
index 8757fdf..a758276 100644
--- a/src/com/android/settings/accessibility/MagnificationFollowTypingPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationFollowTypingPreferenceController.java
@@ -35,6 +35,8 @@
public class MagnificationFollowTypingPreferenceController extends TogglePreferenceController
implements LifecycleObserver {
+ private static final String TAG =
+ MagnificationFollowTypingPreferenceController.class.getSimpleName();
static final String PREF_KEY = "magnification_follow_typing";
private SwitchPreference mFollowTypingPreference;
@@ -75,6 +77,14 @@
// TODO(b/186731461): Remove it when this controller is used in DashBoardFragment only.
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void onResume() {
+ updateState();
+ }
+
+ /**
+ * Updates the state of preference components which has been displayed by
+ * {@link MagnificationFollowTypingPreferenceController#displayPreference}.
+ */
+ void updateState() {
updateState(mFollowTypingPreference);
}
}
diff --git a/src/com/android/settings/accessibility/SettingsContentObserver.java b/src/com/android/settings/accessibility/SettingsContentObserver.java
deleted file mode 100644
index de67f6c..0000000
--- a/src/com/android/settings/accessibility/SettingsContentObserver.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2013 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.settings.accessibility;
-
-import android.content.ContentResolver;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.Settings;
-
-import java.util.ArrayList;
-import java.util.List;
-
-abstract class SettingsContentObserver extends ContentObserver {
- private final List<String> mKeysToObserve = new ArrayList<>(2);
-
- public SettingsContentObserver(Handler handler) {
- super(handler);
- mKeysToObserve.add(Settings.Secure.ACCESSIBILITY_ENABLED);
- mKeysToObserve.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
- }
-
- public SettingsContentObserver(Handler handler, List<String> keysToObserve) {
- this(handler);
- mKeysToObserve.addAll(keysToObserve);
- }
-
- public void register(ContentResolver contentResolver) {
- for (int i = 0; i < mKeysToObserve.size(); i++) {
- contentResolver.registerContentObserver(
- Settings.Secure.getUriFor(mKeysToObserve.get(i)), false, this);
- }
- }
-
- public void unregister(ContentResolver contentResolver) {
- contentResolver.unregisterContentObserver(this);
- }
-
- @Override
- public abstract void onChange(boolean selfChange, Uri uri);
-}
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index 04b5347..0632d3f 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -35,7 +35,6 @@
import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
@@ -65,15 +64,7 @@
private static final String EMPTY_STRING = "";
- private final SettingsContentObserver mSettingsContentObserver =
- new SettingsContentObserver(new Handler()) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateSwitchBarToggleSwitch();
- }
- };
-
- private Dialog mDialog;
+ private Dialog mWarningDialog;
private BroadcastReceiver mPackageRemovedReceiver;
private boolean mDisabledStateLogged = false;
private long mStartTimeMillsForLogging = 0;
@@ -109,6 +100,13 @@
}
@Override
+ protected void registerKeysToObserverCallback(
+ AccessibilitySettingsContentObserver contentObserver) {
+ super.registerKeysToObserverCallback(contentObserver);
+ contentObserver.registerObserverCallback(key -> updateSwitchBarToggleSwitch());
+ }
+
+ @Override
public void onStart() {
super.onStart();
final AccessibilityServiceInfo serviceInfo = getAccessibilityServiceInfo();
@@ -123,7 +121,11 @@
public void onResume() {
super.onResume();
updateSwitchBarToggleSwitch();
- mSettingsContentObserver.register(getContentResolver());
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
}
@Override
@@ -172,7 +174,7 @@
if (info == null) {
return null;
}
- mDialog = AccessibilityServiceWarning
+ mWarningDialog = AccessibilityServiceWarning
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromEnableToggleClicked,
this::onDialogButtonFromUninstallClicked);
@@ -183,7 +185,7 @@
if (info == null) {
return null;
}
- mDialog = AccessibilityServiceWarning
+ mWarningDialog = AccessibilityServiceWarning
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromShortcutToggleClicked,
this::onDialogButtonFromUninstallClicked);
@@ -194,7 +196,7 @@
if (info == null) {
return null;
}
- mDialog = AccessibilityServiceWarning
+ mWarningDialog = AccessibilityServiceWarning
.createCapabilitiesDialog(getPrefContext(), info,
this::onDialogButtonFromShortcutClicked,
this::onDialogButtonFromUninstallClicked);
@@ -205,16 +207,16 @@
if (info == null) {
return null;
}
- mDialog = AccessibilityServiceWarning
+ mWarningDialog = AccessibilityServiceWarning
.createDisableDialog(getPrefContext(), info,
this::onDialogButtonFromDisableToggleClicked);
break;
}
default: {
- mDialog = super.onCreateDialog(dialogId);
+ mWarningDialog = super.onCreateDialog(dialogId);
}
}
- return mDialog;
+ return mWarningDialog;
}
@Override
@@ -402,7 +404,7 @@
}
private void onDialogButtonFromUninstallClicked() {
- mDialog.dismiss();
+ mWarningDialog.dismiss();
final Intent uninstallIntent = createUninstallPackageActivityIntent();
if (uninstallIntent == null) {
return;
@@ -436,12 +438,12 @@
mIsDialogShown.set(false);
showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
}
- mDialog.dismiss();
+ mWarningDialog.dismiss();
}
private void onDenyButtonFromEnableToggleClicked() {
handleConfirmServiceEnabled(/* confirmed= */ false);
- mDialog.dismiss();
+ mWarningDialog.dismiss();
}
void onDialogButtonFromShortcutToggleClicked(View view) {
@@ -465,7 +467,7 @@
mIsDialogShown.set(false);
showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
- mDialog.dismiss();
+ mWarningDialog.dismiss();
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
}
@@ -473,7 +475,7 @@
private void onDenyButtonFromShortcutToggleClicked() {
mShortcutPreference.setChecked(false);
- mDialog.dismiss();
+ mWarningDialog.dismiss();
}
void onDialogButtonFromShortcutClicked(View view) {
@@ -491,11 +493,11 @@
mIsDialogShown.set(false);
showPopupDialog(DialogEnums.EDIT_SHORTCUT);
- mDialog.dismiss();
+ mWarningDialog.dismiss();
}
private void onDenyButtonFromShortcutClicked() {
- mDialog.dismiss();
+ mWarningDialog.dismiss();
}
private boolean onPreferenceClick(boolean isChecked) {
diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
index 419514f..e65c9c5 100644
--- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
@@ -25,7 +25,6 @@
import android.content.ContentResolver;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
@@ -41,8 +40,6 @@
public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePreferenceFragment {
private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED;
- private final Handler mHandler = new Handler();
- private SettingsContentObserver mSettingsContentObserver;
@Override
public int getMetricsCategory() {
@@ -86,20 +83,22 @@
.authority(getPrefContext().getPackageName())
.appendPath(String.valueOf(R.raw.accessibility_color_inversion_banner))
.build();
- final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
- enableServiceFeatureKeys.add(ENABLED);
- mSettingsContentObserver = new SettingsContentObserver(mHandler, enableServiceFeatureKeys) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateSwitchBarToggleSwitch();
- }
- };
-
final View view = super.onCreateView(inflater, container, savedInstanceState);
updateFooterPreference();
return view;
}
+ @Override
+ protected void registerKeysToObserverCallback(
+ AccessibilitySettingsContentObserver contentObserver) {
+ super.registerKeysToObserverCallback(contentObserver);
+
+ final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
+ enableServiceFeatureKeys.add(ENABLED);
+ contentObserver.registerKeysToObserverCallback(enableServiceFeatureKeys,
+ key -> updateSwitchBarToggleSwitch());
+ }
+
private void updateFooterPreference() {
final String title = getPrefContext().getString(
R.string.accessibility_color_inversion_about_title);
@@ -114,12 +113,10 @@
public void onResume() {
super.onResume();
updateSwitchBarToggleSwitch();
- mSettingsContentObserver.register(getContentResolver());
}
@Override
public void onPause() {
- mSettingsContentObserver.unregister(getContentResolver());
super.onPause();
}
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
index c9449d24..f0a4f0a 100644
--- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -24,9 +24,7 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.res.Resources;
-import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
@@ -53,8 +51,6 @@
private static final String KEY_PREVIEW = "daltonizer_preview";
private static final String KEY_CATEGORY_MODE = "daltonizer_mode_category";
private static final List<AbstractPreferenceController> sControllers = new ArrayList<>();
- private final Handler mHandler = new Handler();
- private SettingsContentObserver mSettingsContentObserver;
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
@@ -84,20 +80,22 @@
mComponentName = DALTONIZER_COMPONENT_NAME;
mPackageName = getText(R.string.accessibility_display_daltonizer_preference_title);
mHtmlDescription = getText(R.string.accessibility_display_daltonizer_preference_subtitle);
- final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
- enableServiceFeatureKeys.add(ENABLED);
- mSettingsContentObserver = new SettingsContentObserver(mHandler, enableServiceFeatureKeys) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateSwitchBarToggleSwitch();
- }
- };
-
final View view = super.onCreateView(inflater, container, savedInstanceState);
updateFooterPreference();
return view;
}
+ @Override
+ protected void registerKeysToObserverCallback(
+ AccessibilitySettingsContentObserver contentObserver) {
+ super.registerKeysToObserverCallback(contentObserver);
+
+ final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
+ enableServiceFeatureKeys.add(ENABLED);
+ contentObserver.registerKeysToObserverCallback(enableServiceFeatureKeys,
+ key -> updateSwitchBarToggleSwitch());
+ }
+
private void updateFooterPreference() {
final String title = getPrefContext()
.getString(R.string.accessibility_daltonizer_about_title);
@@ -123,8 +121,6 @@
public void onResume() {
super.onResume();
updateSwitchBarToggleSwitch();
- mSettingsContentObserver.register(getContentResolver());
-
for (AbstractPreferenceController controller :
buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) {
((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(this);
@@ -135,7 +131,6 @@
@Override
public void onPause() {
- mSettingsContentObserver.unregister(getContentResolver());
for (AbstractPreferenceController controller :
buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) {
((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(null);
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 233b7ee..cba5d83 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -99,7 +99,7 @@
protected static final String KEY_ANIMATED_IMAGE = "animated_image";
private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
- private SettingsContentObserver mSettingsContentObserver;
+ private AccessibilitySettingsContentObserver mSettingsContentObserver;
private CheckBox mSoftwareTypeCheckBox;
private CheckBox mHardwareTypeCheckBox;
@@ -143,17 +143,21 @@
setPreferenceScreen(preferenceScreen);
}
- final List<String> shortcutFeatureKeys = getFeatureSettingsKeys();
- mSettingsContentObserver = new SettingsContentObserver(new Handler(), shortcutFeatureKeys) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateShortcutPreferenceData();
- updateShortcutPreference();
- }
- };
+ mSettingsContentObserver = new AccessibilitySettingsContentObserver(new Handler());
+ registerKeysToObserverCallback(mSettingsContentObserver);
}
- protected List<String> getFeatureSettingsKeys() {
+ protected void registerKeysToObserverCallback(
+ AccessibilitySettingsContentObserver contentObserver) {
+ final List<String> shortcutFeatureKeys = getShortcutFeatureSettingsKeys();
+
+ contentObserver.registerKeysToObserverCallback(shortcutFeatureKeys, key -> {
+ updateShortcutPreferenceData();
+ updateShortcutPreference();
+ });
+ }
+
+ protected List<String> getShortcutFeatureSettingsKeys() {
final List<String> shortcutFeatureKeys = new ArrayList<>();
shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
diff --git a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
index 81bd45a..feb41a1 100644
--- a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
@@ -22,7 +22,6 @@
import android.hardware.display.ColorDisplayManager;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
@@ -50,8 +49,6 @@
private static final String KEY_INTENSITY = "rbc_intensity";
private static final String KEY_PERSIST = "rbc_persist";
- private final Handler mHandler = new Handler();
- private SettingsContentObserver mSettingsContentObserver;
private ReduceBrightColorsIntensityPreferenceController mRbcIntensityPreferenceController;
private ReduceBrightColorsPersistencePreferenceController mRbcPersistencePreferenceController;
private ColorDisplayManager mColorDisplayManager;
@@ -67,20 +64,12 @@
mComponentName = AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
mPackageName = getText(R.string.reduce_bright_colors_preference_title);
mHtmlDescription = getText(R.string.reduce_bright_colors_preference_subtitle);
- final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
- enableServiceFeatureKeys.add(REDUCE_BRIGHT_COLORS_ACTIVATED_KEY);
mRbcIntensityPreferenceController =
new ReduceBrightColorsIntensityPreferenceController(getContext(), KEY_INTENSITY);
mRbcPersistencePreferenceController =
new ReduceBrightColorsPersistencePreferenceController(getContext(), KEY_PERSIST);
mRbcIntensityPreferenceController.displayPreference(getPreferenceScreen());
mRbcPersistencePreferenceController.displayPreference(getPreferenceScreen());
- mSettingsContentObserver = new SettingsContentObserver(mHandler, enableServiceFeatureKeys) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateSwitchBarToggleSwitch();
- }
- };
mColorDisplayManager = getContext().getSystemService(ColorDisplayManager.class);
final View view = super.onCreateView(inflater, container, savedInstanceState);
// Parent sets the title when creating the view, so set it after calling super
@@ -90,6 +79,17 @@
return view;
}
+ @Override
+ protected void registerKeysToObserverCallback(
+ AccessibilitySettingsContentObserver contentObserver) {
+ super.registerKeysToObserverCallback(contentObserver);
+
+ final List<String> enableServiceFeatureKeys = new ArrayList<>(/* initialCapacity= */ 1);
+ enableServiceFeatureKeys.add(REDUCE_BRIGHT_COLORS_ACTIVATED_KEY);
+ contentObserver.registerKeysToObserverCallback(enableServiceFeatureKeys,
+ key -> updateSwitchBarToggleSwitch());
+ }
+
private void updateGeneralCategoryOrder() {
final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY);
final SeekBarPreference intensity = findPreference(KEY_INTENSITY);
@@ -117,12 +117,10 @@
public void onResume() {
super.onResume();
updateSwitchBarToggleSwitch();
- mSettingsContentObserver.register(getContentResolver());
}
@Override
public void onPause() {
- mSettingsContentObserver.unregister(getContentResolver());
super.onPause();
}
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index d1e9b56..0867918 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -75,6 +75,7 @@
new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
private DialogCreatable mDialogDelegate;
+ private MagnificationFollowTypingPreferenceController mFollowTypingPreferenceController;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -187,11 +188,10 @@
MagnificationFollowTypingPreferenceController.PREF_KEY);
generalCategory.addPreference(followingTypingSwitchPreference);
- final MagnificationFollowTypingPreferenceController followTypingPreferenceController =
- new MagnificationFollowTypingPreferenceController(getContext(),
- MagnificationFollowTypingPreferenceController.PREF_KEY);
- getSettingsLifecycle().addObserver(followTypingPreferenceController);
- followTypingPreferenceController.displayPreference(getPreferenceScreen());
+ mFollowTypingPreferenceController = new MagnificationFollowTypingPreferenceController(
+ getContext(), MagnificationFollowTypingPreferenceController.PREF_KEY);
+ getSettingsLifecycle().addObserver(mFollowTypingPreferenceController);
+ mFollowTypingPreferenceController.displayPreference(getPreferenceScreen());
}
@Override
@@ -293,8 +293,23 @@
}
@Override
- protected List<String> getFeatureSettingsKeys() {
- final List<String> shortcutKeys = super.getFeatureSettingsKeys();
+ protected void registerKeysToObserverCallback(
+ AccessibilitySettingsContentObserver contentObserver) {
+ super.registerKeysToObserverCallback(contentObserver);
+
+ final List<String> followingTypingKeys = new ArrayList<>();
+ followingTypingKeys.add(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED);
+ contentObserver.registerKeysToObserverCallback(followingTypingKeys,
+ key -> updateFollowTypingState());
+ }
+
+ private void updateFollowTypingState() {
+ mFollowTypingPreferenceController.updateState();
+ }
+
+ @Override
+ protected List<String> getShortcutFeatureSettingsKeys() {
+ final List<String> shortcutKeys = super.getShortcutFeatureSettingsKeys();
shortcutKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
return shortcutKeys;
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsContentObserverTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsContentObserverTest.java
new file mode 100644
index 0000000..e23d2d7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsContentObserverTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2022 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.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowContentResolver;
+
+import java.util.Collection;
+import java.util.List;
+
+/** Test for {@link AccessibilitySettingsContentObserver}. */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilitySettingsContentObserverTest {
+
+ private static final String SPECIFIC_KEY_A_1 = "SPECIFIC_KEY_A_1";
+ private static final String SPECIFIC_KEY_A_2 = "SPECIFIC_KEY_A_2";
+ private static final String SPECIFIC_KEY_B_1 = "SPECIFIC_KEY_B_1";
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private final AccessibilitySettingsContentObserver mObserver =
+ new AccessibilitySettingsContentObserver(new Handler());
+ private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackA =
+ spy(new TestableContentObserverCallback());
+ private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackB =
+ spy(new TestableContentObserverCallback());
+ private final ContentResolver mContentResolver = mContext.getContentResolver();
+
+ @Test
+ public void register_shouldRegisterContentObserverForDefaultKeys() {
+ mObserver.register(mContentResolver);
+
+ ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
+ assertObserverToUri(shadowContentResolver,
+ Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
+ assertObserverToUri(shadowContentResolver,
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
+ }
+
+ @Test
+ public void unregister_shouldUnregisterContentObserver() {
+ mObserver.register(mContentResolver);
+
+ mObserver.unregister(mContentResolver);
+
+ ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
+ assertNotObserverToUri(shadowContentResolver, Settings.Secure.ACCESSIBILITY_ENABLED);
+ assertNotObserverToUri(shadowContentResolver,
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ }
+
+ @Test
+ public void register_addSpecificKeys_shouldRegisterContentObserverForSpecificAndDefaultKeys() {
+ mObserver.registerKeysToObserverCallback(List.of(SPECIFIC_KEY_A_1), mObserverCallbackA);
+
+ mObserver.register(mContentResolver);
+
+ ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
+ assertObserverToUri(shadowContentResolver,
+ Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
+ assertObserverToUri(shadowContentResolver,
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
+ assertObserverToUri(shadowContentResolver, SPECIFIC_KEY_A_1, mObserver);
+ }
+
+ @Test
+ public void onChange_shouldTriggerCallbackOnDefaultKey() {
+ mObserver.registerObserverCallback(mObserverCallbackA);
+ mObserver.register(mContentResolver);
+
+ mObserver.onChange(/* selfChange= */ false,
+ Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_ENABLED));
+
+ verify(mObserverCallbackA).onChange(Settings.Secure.ACCESSIBILITY_ENABLED);
+ }
+
+ @Test
+ public void onChange_registerSpecificKeys_shouldTriggerSpecificCallback() {
+ mObserver.registerKeysToObserverCallback(
+ List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
+ mObserver.register(mContentResolver);
+
+ mObserver.onChange(/* selfChange= */ false,
+ Settings.Secure.getUriFor(SPECIFIC_KEY_A_2));
+
+ verify(mObserverCallbackA).onChange(SPECIFIC_KEY_A_2);
+ }
+
+ @Test
+ public void onChange_registerSpecificKeys_withoutTriggerOtherCallback() {
+ mObserver.registerKeysToObserverCallback(
+ List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
+ mObserver.registerKeysToObserverCallback(
+ List.of(SPECIFIC_KEY_B_1), mObserverCallbackB);
+ mObserver.register(mContentResolver);
+
+ mObserver.onChange(/* selfChange= */ false,
+ Settings.Secure.getUriFor(SPECIFIC_KEY_B_1));
+
+ verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_1);
+ verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_2);
+ verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_B_1);
+ verify(mObserverCallbackB).onChange(SPECIFIC_KEY_B_1);
+ }
+
+ @After
+ public void tearDown() {
+ mObserver.unregister(mContentResolver);
+ }
+
+ private void assertNotObserverToUri(ShadowContentResolver resolver, String key) {
+ assertThat(resolver.getContentObservers(Settings.Secure.getUriFor(key))).isEmpty();
+ }
+
+ private void assertObserverToUri(ShadowContentResolver resolver,
+ String key, ContentObserver observer) {
+ Collection<ContentObserver> observers =
+ resolver.getContentObservers(Settings.Secure.getUriFor(key));
+ assertThat(observers).contains(observer);
+ }
+
+ private static class TestableContentObserverCallback implements
+ AccessibilitySettingsContentObserver.ContentObserverCallback {
+ @Override
+ public void onChange(String key) {
+ // do nothing
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index d1c59f7..5843265 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
@@ -281,10 +281,10 @@
verify(mContentResolver).registerContentObserver(
eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)),
anyBoolean(),
- any(SettingsContentObserver.class));
+ any(AccessibilitySettingsContentObserver.class));
verify(mContentResolver).registerContentObserver(eq(Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)), anyBoolean(),
- any(SettingsContentObserver.class));
+ any(AccessibilitySettingsContentObserver.class));
verify(mActivity, atLeast(1)).registerReceiver(any(PackageMonitor.class), captor.capture(),
isNull(), any());
intentFilter = captor.getAllValues().get(/* first time */ 0);
@@ -301,7 +301,8 @@
mFragment.onDestroy();
- verify(mContentResolver).unregisterContentObserver(any(SettingsContentObserver.class));
+ verify(mContentResolver).unregisterContentObserver(
+ any(AccessibilitySettingsContentObserver.class));
verify(mActivity).unregisterReceiver(any(PackageMonitor.class));
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationFollowTypingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationFollowTypingPreferenceControllerTest.java
index ccb66ad..fd282a0 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationFollowTypingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationFollowTypingPreferenceControllerTest.java
@@ -94,4 +94,15 @@
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
+
+ @Test
+ public void updateState_disableFollowTyping_shouldReturnFalse() {
+ Settings.Secure.putInt(mContext.getContentResolver(), KEY_FOLLOW_TYPING, OFF);
+
+ mController.updateState();
+
+ verify(mSwitchPreference).setChecked(false);
+ assertThat(mController.isChecked()).isFalse();
+ assertThat(mSwitchPreference.isChecked()).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
index c47a793..4584b15 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
@@ -20,6 +20,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -27,6 +29,7 @@
import static org.mockito.Mockito.when;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
@@ -75,12 +78,16 @@
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
private TestToggleFeaturePreferenceFragment mFragment;
- private PreferenceScreen mScreen;
- private Context mContext = ApplicationProvider.getApplicationContext();
+ private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceManager mPreferenceManager;
+ @Mock
+ private FragmentActivity mActivity;
+ @Mock
+ private ContentResolver mContentResolver;
+
@Before
public void setUpTestFragment() {
MockitoAnnotations.initMocks(this);
@@ -89,9 +96,11 @@
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
when(mFragment.getContext()).thenReturn(mContext);
- mScreen = spy(new PreferenceScreen(mContext, null));
- when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
- doReturn(mScreen).when(mFragment).getPreferenceScreen();
+ when(mFragment.getActivity()).thenReturn(mActivity);
+ when(mActivity.getContentResolver()).thenReturn(mContentResolver);
+ final PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
+ when(screen.getPreferenceManager()).thenReturn(mPreferenceManager);
+ doReturn(screen).when(mFragment).getPreferenceScreen();
}
@Test
@@ -104,6 +113,25 @@
}
@Test
+ @Config(shadows = {ShadowFragment.class})
+ public void onResume_haveRegisterToSpecificUris() {
+ mFragment.onAttach(mContext);
+ mFragment.onCreate(Bundle.EMPTY);
+
+ mFragment.onResume();
+
+ verify(mContentResolver).registerContentObserver(
+ eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)),
+ eq(false),
+ any(AccessibilitySettingsContentObserver.class));
+ verify(mContentResolver).registerContentObserver(
+ eq(Settings.Secure.getUriFor(
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)),
+ eq(false),
+ any(AccessibilitySettingsContentObserver.class));
+ }
+
+ @Test
public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
index 10495c5..8500e61 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
@@ -25,14 +25,15 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
@@ -63,8 +64,8 @@
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@@ -96,17 +97,22 @@
private Context mContext;
private Resources mResources;
+ @Mock
+ private FragmentActivity mActivity;
+ @Mock
+ private ContentResolver mContentResolver;
+
@Before
public void setUpTestFragment() {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
- final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
mFragment = spy(new TestToggleScreenMagnificationPreferenceFragment(mContext));
mResources = spy(mContext.getResources());
when(mContext.getResources()).thenReturn(mResources);
when(mFragment.getContext().getResources()).thenReturn(mResources);
- doReturn(activity).when(mFragment).getActivity();
+ when(mFragment.getActivity()).thenReturn(mActivity);
+ when(mActivity.getContentResolver()).thenReturn(mContentResolver);
}
@Ignore("Ignore it since a NPE is happened in ShadowWindowManagerGlobal. (Ref. b/214161063)")
@@ -143,6 +149,30 @@
}
@Test
+ @Config(shadows = {ShadowFragment.class})
+ public void onResume_haveRegisterToSpecificUris() {
+ mFragment.onAttach(mContext);
+ mFragment.onCreate(Bundle.EMPTY);
+
+ mFragment.onResume();
+
+ verify(mContentResolver).registerContentObserver(
+ eq(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS)),
+ eq(false),
+ any(AccessibilitySettingsContentObserver.class));
+ verify(mContentResolver).registerContentObserver(
+ eq(Settings.Secure.getUriFor(
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)),
+ eq(false),
+ any(AccessibilitySettingsContentObserver.class));
+ verify(mContentResolver).registerContentObserver(
+ eq(Settings.Secure.getUriFor(
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED)),
+ eq(false),
+ any(AccessibilitySettingsContentObserver.class));
+ }
+
+ @Test
public void hasValueInSettings_putValue_hasValue() {
setMagnificationTripleTapEnabled(/* enabled= */ true);