diff --git a/aconfig/accessibility/accessibility_flags.aconfig b/aconfig/accessibility/accessibility_flags.aconfig
index 2b843cd79b6..691999005cb 100644
--- a/aconfig/accessibility/accessibility_flags.aconfig
+++ b/aconfig/accessibility/accessibility_flags.aconfig
@@ -24,6 +24,16 @@ flag {
bug: "301198830"
}
+flag {
+ name: "hide_magnification_always_on_toggle_when_window_mode_only"
+ namespace: "accessibility"
+ description: "Decides whether to hide the magnification always on setting when capabilities is window mode only."
+ bug: "328787031"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
flag {
name: "remove_qs_tooltip_in_suw"
namespace: "accessibility"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index abf018cbe4a..cc75e6778d5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4764,6 +4764,8 @@
Keep on while switching apps
Magnifier stays on and zooms out when you switch apps
+
+ Unavailable while only magnifying part of the screen
Joystick
diff --git a/src/com/android/settings/accessibility/MagnificationAlwaysOnPreferenceController.java b/src/com/android/settings/accessibility/MagnificationAlwaysOnPreferenceController.java
index f3d857580aa..4a37a416414 100644
--- a/src/com/android/settings/accessibility/MagnificationAlwaysOnPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationAlwaysOnPreferenceController.java
@@ -20,26 +20,73 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
import android.provider.Settings;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
import com.android.settings.R;
+import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
/**
* Controller that accesses and switches the preference status of the magnification always on
* feature, where the magnifier will not deactivate on Activity transitions; it will only zoom out
* to 100%.
*/
-public class MagnificationAlwaysOnPreferenceController extends TogglePreferenceController {
+public class MagnificationAlwaysOnPreferenceController extends TogglePreferenceController
+ implements LifecycleObserver, OnResume, OnPause {
private static final String TAG =
MagnificationAlwaysOnPreferenceController.class.getSimpleName();
static final String PREF_KEY = Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED;
+ private Preference mPreference;
+
+ @VisibleForTesting
+ final ContentObserver mContentObserver = new ContentObserver(
+ new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange, @Nullable Uri uri) {
+ updateState(mPreference);
+ }
+ };
+
public MagnificationAlwaysOnPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
+ @Override
+ public void onResume() {
+ if (Flags.hideMagnificationAlwaysOnToggleWhenWindowModeOnly()) {
+ MagnificationCapabilities.registerObserver(mContext, mContentObserver);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (Flags.hideMagnificationAlwaysOnToggleWhenWindowModeOnly()) {
+ MagnificationCapabilities.unregisterObserver(mContext, mContentObserver);
+ }
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ updateState(mPreference);
+ }
+
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
@@ -62,4 +109,33 @@ public class MagnificationAlwaysOnPreferenceController extends TogglePreferenceC
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
+
+ @Override
+ public CharSequence getSummary() {
+ if (!Flags.hideMagnificationAlwaysOnToggleWhenWindowModeOnly()) {
+ return super.getSummary();
+ }
+
+ @StringRes int resId = mPreference.isEnabled()
+ ? R.string.accessibility_screen_magnification_always_on_summary
+ : R.string.accessibility_screen_magnification_always_on_unavailable_summary;
+ return mContext.getString(resId);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (!Flags.hideMagnificationAlwaysOnToggleWhenWindowModeOnly()) {
+ return;
+ }
+
+ if (preference == null) {
+ return;
+ }
+ @MagnificationMode int mode =
+ MagnificationCapabilities.getCapabilities(mContext);
+ preference.setEnabled(
+ mode == MagnificationMode.FULLSCREEN || mode == MagnificationMode.ALL);
+ refreshSummary(preference);
+ }
}
diff --git a/src/com/android/settings/accessibility/MagnificationCapabilities.java b/src/com/android/settings/accessibility/MagnificationCapabilities.java
index 04a2992f011..eb2ba5356c9 100644
--- a/src/com/android/settings/accessibility/MagnificationCapabilities.java
+++ b/src/com/android/settings/accessibility/MagnificationCapabilities.java
@@ -18,6 +18,7 @@ package com.android.settings.accessibility;
import android.content.ContentResolver;
import android.content.Context;
+import android.database.ContentObserver;
import android.provider.Settings;
import androidx.annotation.IntDef;
@@ -101,5 +102,28 @@ public final class MagnificationCapabilities {
MagnificationMode.FULLSCREEN, contentResolver.getUserId());
}
+ /**
+ * Register an observer class that gets callbacks when magnification capabilities changes.
+ *
+ * @param context A {@link Context}.
+ * @param contentObserver The object that receives callbacks when changes occur.
+ */
+ public static void registerObserver(Context context, ContentObserver contentObserver) {
+ context.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(KEY_CAPABILITY),
+ /* notifyForDescendants= */ false,
+ contentObserver);
+ }
+
+ /**
+ * Unregisters a magnification capabilities change observer.
+ *
+ * @param context A {@link Context}.
+ * @param contentObserver The previously registered observer that is no longer needed.
+ */
+ public static void unregisterObserver(Context context, ContentObserver contentObserver) {
+ context.getContentResolver().unregisterContentObserver(contentObserver);
+ }
+
private MagnificationCapabilities() {}
}
diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index 630c24e3cae..d162272fdb6 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -266,6 +266,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
defaultValue
);
}
+
private void addAlwaysOnSetting(PreferenceCategory generalCategory) {
if (!isAlwaysOnSettingEnabled()) {
return;
@@ -282,6 +283,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
var alwaysOnPreferenceController = new MagnificationAlwaysOnPreferenceController(
getContext(), MagnificationAlwaysOnPreferenceController.PREF_KEY);
+ getSettingsLifecycle().addObserver(alwaysOnPreferenceController);
alwaysOnPreferenceController.displayPreference(getPreferenceScreen());
addPreferenceController(alwaysOnPreferenceController);
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationAlwaysOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationAlwaysOnPreferenceControllerTest.java
index 417c3d412aa..3e97cec0f4a 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationAlwaysOnPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationAlwaysOnPreferenceControllerTest.java
@@ -17,6 +17,7 @@
package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import static com.google.common.truth.Truth.assertThat;
@@ -25,6 +26,9 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
@@ -33,31 +37,42 @@ import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowContentResolver;
@RunWith(RobolectricTestRunner.class)
public class MagnificationAlwaysOnPreferenceControllerTest {
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private static final String KEY_ALWAYS_ON =
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED;
- private final Context mContext = ApplicationProvider.getApplicationContext();
- private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
- private final MagnificationAlwaysOnPreferenceController mController =
- new MagnificationAlwaysOnPreferenceController(mContext,
- MagnificationAlwaysOnPreferenceController.PREF_KEY);
+ private Context mContext;
+ private ShadowContentResolver mShadowContentResolver;
+ private SwitchPreference mSwitchPreference;
+ private MagnificationAlwaysOnPreferenceController mController;
@Before
public void setUp() {
+ mContext = ApplicationProvider.getApplicationContext();
+ mShadowContentResolver = Shadow.extract(mContext.getContentResolver());
+
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
+ mSwitchPreference = spy(new SwitchPreference(mContext));
mSwitchPreference.setKey(MagnificationAlwaysOnPreferenceController.PREF_KEY);
screen.addPreference(mSwitchPreference);
- mController.displayPreference(screen);
+ mController = new MagnificationAlwaysOnPreferenceController(mContext,
+ MagnificationAlwaysOnPreferenceController.PREF_KEY);
+ mController.displayPreference(screen);
mController.updateState(mSwitchPreference);
+
reset(mSwitchPreference);
}
@@ -80,4 +95,57 @@ public class MagnificationAlwaysOnPreferenceControllerTest {
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_HIDE_MAGNIFICATION_ALWAYS_ON_TOGGLE_WHEN_WINDOW_MODE_ONLY)
+ public void onResume_flagOn_verifyRegisterCapabilityObserver() {
+ mController.onResume();
+ assertThat(mShadowContentResolver.getContentObservers(
+ Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY)))
+ .hasSize(1);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_HIDE_MAGNIFICATION_ALWAYS_ON_TOGGLE_WHEN_WINDOW_MODE_ONLY)
+ public void onPause_flagOn_verifyUnregisterCapabilityObserver() {
+ mController.onResume();
+ mController.onPause();
+ assertThat(mShadowContentResolver.getContentObservers(
+ Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY)))
+ .isEmpty();
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_HIDE_MAGNIFICATION_ALWAYS_ON_TOGGLE_WHEN_WINDOW_MODE_ONLY)
+ public void updateState_windowModeOnlyAndFlagOff_preferenceIsAvailable() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
+
+ mController.updateState(mSwitchPreference);
+ assertThat(mSwitchPreference.isEnabled()).isTrue();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_HIDE_MAGNIFICATION_ALWAYS_ON_TOGGLE_WHEN_WINDOW_MODE_ONLY)
+ public void updateState_windowModeOnlyAndFlagOn_preferenceBecomesUnavailable() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
+
+ mController.updateState(mSwitchPreference);
+ assertThat(mSwitchPreference.isEnabled()).isFalse();
+ }
+
+ @Test
+ public void updateState_fullscreenModeOnly_preferenceIsAvailable() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.FULLSCREEN);
+
+ mController.updateState(mSwitchPreference);
+ assertThat(mSwitchPreference.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void updateState_switchMode_preferenceIsAvailable() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
+
+ mController.updateState(mSwitchPreference);
+ assertThat(mSwitchPreference.isEnabled()).isTrue();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationCapabilitiesTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationCapabilitiesTest.java
index b0d03564c75..754b1a7f38e 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationCapabilitiesTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationCapabilitiesTest.java
@@ -18,7 +18,14 @@ package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
+import android.database.ContentObserver;
import androidx.test.core.app.ApplicationProvider;
@@ -42,7 +49,6 @@ public final class MagnificationCapabilitiesTest {
final int windowCapabilities = MagnificationCapabilities.getCapabilities(mContext);
assertThat(windowCapabilities).isEqualTo(
MagnificationCapabilities.MagnificationMode.WINDOW);
-
}
@Test
@@ -63,4 +69,35 @@ public final class MagnificationCapabilitiesTest {
assertThat(windowCapabilities).isEqualTo(
MagnificationCapabilities.MagnificationMode.FULLSCREEN);
}
+
+ @Test
+ public void registerObserver_triggeredWhenCapabilitiesChanged() {
+ MagnificationCapabilities.setCapabilities(mContext,
+ MagnificationCapabilities.MagnificationMode.FULLSCREEN);
+
+ ContentObserver contentObserver =
+ spy(new ContentObserver(/* handler= */ null) {});
+
+ MagnificationCapabilities.registerObserver(mContext, contentObserver);
+ MagnificationCapabilities.setCapabilities(mContext,
+ MagnificationCapabilities.MagnificationMode.WINDOW);
+
+ verify(contentObserver).onChange(/* selfChange= */ anyBoolean(), /* uri= */ any());
+ }
+
+ @Test
+ public void unregisterObserver_neverTriggeredWhenCapabilitiesChanged() {
+ MagnificationCapabilities.setCapabilities(mContext,
+ MagnificationCapabilities.MagnificationMode.FULLSCREEN);
+
+ ContentObserver contentObserver =
+ spy(new ContentObserver(/* handler= */ null) {});
+
+ MagnificationCapabilities.registerObserver(mContext, contentObserver);
+ MagnificationCapabilities.unregisterObserver(mContext, contentObserver);
+ MagnificationCapabilities.setCapabilities(mContext,
+ MagnificationCapabilities.MagnificationMode.WINDOW);
+
+ verify(contentObserver, never()).onChange(/* selfChange= */ anyBoolean(), /* uri= */ any());
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
index 1d85705a9e7..cc1c72ea10e 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
@@ -816,6 +816,21 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
assertThat(lifecycleObservers).comparingElementsUsing(instanceOf).contains(true);
}
+ @Test
+ public void onCreateView_addTheAlwaysOnControllerToLifeCycleObserver() {
+ Correspondence instanceOf = Correspondence.transforming(
+ observer -> (observer instanceof MagnificationAlwaysOnPreferenceController),
+ "contains MagnificationAlwaysOnPreferenceController");
+
+ ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create(
+ R.id.main_content, /* bundle= */ null).start().resume().get();
+
+ List lifecycleObservers = ReflectionHelpers.getField(
+ fragment.getSettingsLifecycle(), "mObservers");
+ assertThat(lifecycleObservers).isNotNull();
+ assertThat(lifecycleObservers).comparingElementsUsing(instanceOf).contains(true);
+ }
+
@Test
public void onCreateDialog_setDialogDelegate_invokeDialogDelegate() {
ToggleScreenMagnificationPreferenceFragment fragment =