feat(onefingerpan): hide the one finger pan settings when window mode only
Like MagnificationAlwaysOn toggle behavior, when the magnification
capability is window-mode only we'll hide the OneFingerPan toggle too.
Also do a small refactoring in MagnificationOneFingerPanningPreferenceControllerTest
Bug: 333821725
Flag: ACONFIG com.android.server.accessibility.enable_magnification_one_finger_panning_gesture TEAMFOOD
Test: manually
atest MagnificationOneFingerPanningPreferenceControllerTest
atest ToggleScreenMagnificationPreferenceFragmentTest
Change-Id: I8684b5bae5cbfc5b75fc4c14d2e9173b17d0fb02
diff --git a/res/values/strings.xml b/res/values/strings.xml
index efbc430..8546092 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4816,6 +4816,8 @@
<!-- Summary for accessibility magnification preference when one finger panning feature is turned off.
The feature when disabled, allows user to move the magnification area by dragging two fingers instead of one. [CHAR LIMIT=60] -->
<string name="accessibility_magnification_one_finger_panning_summary_off">Move the magnification area by dragging two fingers.</string>
+ <!-- Summary for accessibility magnification preference when one finger panning feature is unavailable while partial-only capability. [CHAR LIMIT=none] -->
+ <string name="accessibility_magnification_one_finger_panning_summary_unavailable">Unavailable while only magnifying part of the screen</string>
<!-- Title for the accessibility preference screen to enable navigation bar screen magnification. [CHAR LIMIT=35] -->
<string name="accessibility_screen_magnification_navbar_title">Magnify with shortcut</string>
<!-- Summary for the accessibility magnification setting indicating both "Magnify with button" and "Magnify with triple-tap" are enabled [CHAR LIMIT=50] -->
diff --git a/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java b/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java
index a2ce948..4eb5090 100644
--- a/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java
@@ -21,27 +21,43 @@
import android.content.Context;
import android.content.res.Resources;
+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.VisibleForTesting;
+import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.TwoStatePreference;
-import com.android.server.accessibility.Flags;
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;
public class MagnificationOneFingerPanningPreferenceController
- extends TogglePreferenceController {
+ extends TogglePreferenceController implements LifecycleObserver, OnResume, OnPause {
static final String PREF_KEY = Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
- @Nullable
private TwoStatePreference mSwitchPreference;
@VisibleForTesting
final boolean mDefaultValue;
+ @VisibleForTesting
+ final ContentObserver mContentObserver = new ContentObserver(
+ new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange, @Nullable Uri uri) {
+ updateState(mSwitchPreference);
+ }
+ };
+
public MagnificationOneFingerPanningPreferenceController(Context context) {
super(context, PREF_KEY);
boolean defaultValue;
@@ -55,9 +71,18 @@
}
@Override
+ public void onResume() {
+ MagnificationCapabilities.registerObserver(mContext, mContentObserver);
+ }
+
+ @Override
+ public void onPause() {
+ MagnificationCapabilities.unregisterObserver(mContext, mContentObserver);
+ }
+
+ @Override
public int getAvailabilityStatus() {
- return (Flags.enableMagnificationOneFingerPanningGesture())
- ? AVAILABLE : DISABLED_FOR_USER;
+ return AVAILABLE;
}
@Override
@@ -73,14 +98,17 @@
var toReturn = Settings.Secure.putInt(mContext.getContentResolver(),
PREF_KEY,
(isChecked ? ON : OFF));
- if (mSwitchPreference != null) {
- refreshSummary(mSwitchPreference);
- }
+ refreshSummary(mSwitchPreference);
return toReturn;
}
@Override
public CharSequence getSummary() {
+ if (!mSwitchPreference.isEnabled()) {
+ return mContext.getString(
+ R.string.accessibility_magnification_one_finger_panning_summary_unavailable);
+ }
+
return (isChecked())
? mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_on)
@@ -97,6 +125,20 @@
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mSwitchPreference = screen.findPreference(getPreferenceKey());
- refreshSummary(mSwitchPreference);
+ updateState(mSwitchPreference);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ 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/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
index d162272..e965a0d 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -202,7 +202,6 @@
final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY);
generalCategory.addPreference(mSettingsPreference);
- addOneFingerPanningSetting(generalCategory);
final MagnificationModePreferenceController magnificationModePreferenceController =
new MagnificationModePreferenceController(getContext(),
MagnificationModePreferenceController.PREF_KEY);
@@ -212,6 +211,7 @@
addPreferenceController(magnificationModePreferenceController);
addFollowTypingSetting(generalCategory);
+ addOneFingerPanningSetting(generalCategory);
addAlwaysOnSetting(generalCategory);
addJoystickSetting(generalCategory);
}
@@ -302,6 +302,7 @@
var oneFingerPanningPreferenceController =
new MagnificationOneFingerPanningPreferenceController(getContext());
+ getSettingsLifecycle().addObserver(oneFingerPanningPreferenceController);
oneFingerPanningPreferenceController.displayPreference(getPreferenceScreen());
addPreferenceController(oneFingerPanningPreferenceController);
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java
index 4501d27..bfc8313 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java
@@ -18,19 +18,15 @@
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
+import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.Context;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
@@ -38,131 +34,137 @@
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
-import com.android.server.accessibility.Flags;
import com.android.settings.R;
-import org.junit.After;
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 MagnificationOneFingerPanningPreferenceControllerTest {
private static final String ONE_FINGER_PANNING_KEY =
Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
- @Rule
- public final CheckFlagsRule mCheckFlagsRule =
- DeviceFlagsValueProvider.createCheckFlagsRule();
-
private final Context mContext = ApplicationProvider.getApplicationContext();
+ private ShadowContentResolver mShadowContentResolver;
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
private final MagnificationOneFingerPanningPreferenceController mController =
new MagnificationOneFingerPanningPreferenceController(mContext);
- private PreferenceScreen mScreen;
-
@Before
public void setUp() {
+ mShadowContentResolver = Shadow.extract(mContext.getContentResolver());
+
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
- mScreen = preferenceManager.createPreferenceScreen(mContext);
+ final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
mSwitchPreference.setKey(MagnificationOneFingerPanningPreferenceController.PREF_KEY);
- mScreen.addPreference(mSwitchPreference);
- mController.displayPreference(mScreen);
- }
-
- @After
- public void cleanup() {
- // Can't use resetToDefaults as it NPE with
- // "Cannot invoke "android.content.IContentProvider.call"
- Settings.Secure.putInt(
- mContext.getContentResolver(),
- MagnificationOneFingerPanningPreferenceController.PREF_KEY,
- (mController.mDefaultValue) ? ON : OFF);
+ screen.addPreference(mSwitchPreference);
+ mController.displayPreference(screen);
}
@Test
- public void displayPreference_defaultState_correctSummarySet() {
- assertThat(mSwitchPreference.getSummary())
- .isEqualTo(mContext.getString(
- R.string.accessibility_magnification_one_finger_panning_summary_off));
+ public void onResume_verifyRegisterCapabilityObserver() {
+ mController.onResume();
+ assertThat(mShadowContentResolver.getContentObservers(
+ Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY)))
+ .hasSize(1);
}
@Test
- @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
- public void getAvailabilityStatus_flagDisabled_disabled() {
- int status = mController.getAvailabilityStatus();
-
- assertThat(status).isEqualTo(DISABLED_FOR_USER);
+ public void onPause_verifyUnregisterCapabilityObserver() {
+ mController.onResume();
+ mController.onPause();
+ assertThat(mShadowContentResolver.getContentObservers(
+ Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY)))
+ .isEmpty();
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
- public void getAvailabilityStatus_featureFlagEnabled_enabled() {
- int status = mController.getAvailabilityStatus();
+ public void updateState_windowModeOnly_preferenceIsUnavailable() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
+ mController.updateState(mSwitchPreference);
- assertThat(status).isEqualTo(AVAILABLE);
+ 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();
}
@Test
public void isChecked_defaultState_returnFalse() {
+ mController.updateState(mSwitchPreference);
+
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
@Test
- public void isChecked_settingsEnabled_returnTrue() {
+ public void isChecked_settingsOn_returnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
+ mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isTrue();
}
@Test
- public void isChecked_settingsDisabled_returnTrue() {
+ public void isChecked_settingsOff_returnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, OFF);
+ mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isFalse();
}
@Test
- public void setChecked_enabled_enabledSummarySet() {
- mController.setChecked(true);
-
- assertThat(mSwitchPreference.getSummary()).isEqualTo(enabledSummary());
- assertThat(mController.isChecked()).isTrue();
- }
-
- @Test
- public void setChecked_disabled_disabledSummarySet() {
- mController.setChecked(false);
-
- assertThat(mController.isChecked()).isFalse();
- assertThat(mSwitchPreference.getSummary()).isEqualTo(disabledSummary());
- }
-
- @Test
- public void getSummary_disable_disableSummaryTextUsed() {
+ public void getSummary_switchModeAndSettingsOff_disabledSummaryTextUsed() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, OFF);
- var summary = mController.getSummary();
+ mController.updateState(mSwitchPreference);
- assertThat(summary).isEqualTo(disabledSummary());
+ assertThat(mController.getSummary()).isEqualTo(disabledSummary());
}
@Test
- public void getSummary_enable_enabledSummaryTextUsed() {
+ public void getSummary_switchModeAndSettingsOn_enabledSummaryTextUsed() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
- var summary = mController.getSummary();
+ mController.updateState(mSwitchPreference);
- assertThat(summary).isEqualTo(enabledSummary());
+ assertThat(mController.getSummary()).isEqualTo(enabledSummary());
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
- public void performClick_switchDefaultState_shouldReturnTrue() {
+ public void getSummary_windowModeOnly_unavailableSummaryTextUsed() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
+
+ mController.updateState(mSwitchPreference);
+
+ assertThat(mController.getSummary()).isEqualTo(unavailableSummary());
+ }
+
+ @Test
+ public void performClick_defaultSettings_toggleOn() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
+ mController.updateState(mSwitchPreference);
+ reset(mSwitchPreference);
+
mSwitchPreference.performClick();
verify(mSwitchPreference).setChecked(true);
@@ -170,6 +172,20 @@
assertThat(mSwitchPreference.isChecked()).isTrue();
}
+ @Test
+ public void performClick_settingsOn_toggleOff() {
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
+ Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON);
+ mController.updateState(mSwitchPreference);
+ reset(mSwitchPreference);
+
+ mSwitchPreference.performClick();
+
+ verify(mSwitchPreference).setChecked(false);
+ assertThat(mController.isChecked()).isFalse();
+ assertThat(mSwitchPreference.isChecked()).isFalse();
+ }
+
private String enabledSummary() {
return mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_on);
@@ -179,4 +195,9 @@
return mContext.getString(
R.string.accessibility_magnification_one_finger_panning_summary_off);
}
+
+ private String unavailableSummary() {
+ return mContext.getString(
+ R.string.accessibility_magnification_one_finger_panning_summary_unavailable);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
index cc1c72e..ab2e9d1 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java
@@ -122,6 +122,8 @@
private static final String KEY_FOLLOW_TYPING =
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED;
+ private static final String KEY_SINGLE_FINGER_PANNING =
+ Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
private static final String KEY_ALWAYS_ON =
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED;
private static final String KEY_JOYSTICK =
@@ -216,6 +218,43 @@
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
+ public void onResume_defaultStateForOneFingerPan_switchPreferenceShouldReturnFalse() {
+ mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
+
+ final TwoStatePreference switchPreference = mFragController.get().findPreference(
+ MagnificationOneFingerPanningPreferenceController.PREF_KEY);
+ assertThat(switchPreference).isNotNull();
+ assertThat(switchPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
+ public void onResume_enableOneFingerPan_switchPreferenceShouldReturnTrue() {
+ setKeyOneFingerPanEnabled(true);
+
+ mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
+
+ final TwoStatePreference switchPreference = mFragController.get().findPreference(
+ MagnificationOneFingerPanningPreferenceController.PREF_KEY);
+ assertThat(switchPreference).isNotNull();
+ assertThat(switchPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
+ public void onResume_disableOneFingerPan_switchPreferenceShouldReturnFalse() {
+ setKeyOneFingerPanEnabled(false);
+
+ mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
+
+ final TwoStatePreference switchPreference = mFragController.get().findPreference(
+ MagnificationOneFingerPanningPreferenceController.PREF_KEY);
+ assertThat(switchPreference).isNotNull();
+ assertThat(switchPreference.isChecked()).isFalse();
+ }
+
+ @Test
public void onResume_defaultStateForAlwaysOn_switchPreferenceShouldReturnTrue() {
setAlwaysOnSupported(true);
@@ -778,6 +817,16 @@
}
@Test
+ @DisableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
+ public void onCreateView_oneFingerPanNotSupported_settingsPreferenceIsNull() {
+ mFragController.create(R.id.main_content, /* bundle= */ null).start().resume();
+
+ final TwoStatePreference switchPreference = mFragController.get().findPreference(
+ MagnificationOneFingerPanningPreferenceController.PREF_KEY);
+ assertThat(switchPreference).isNull();
+ }
+
+ @Test
public void onCreateView_alwaysOnNotSupported_settingsPreferenceIsNull() {
setAlwaysOnSupported(false);
@@ -817,7 +866,25 @@
}
@Test
- public void onCreateView_addTheAlwaysOnControllerToLifeCycleObserver() {
+ @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
+ public void onCreateView_oneFingerPanSupported_addControllerToLifeCycleObserver() {
+ Correspondence instanceOf = Correspondence.transforming(
+ observer -> (observer instanceof MagnificationOneFingerPanningPreferenceController),
+ "contains MagnificationOneFingerPanningPreferenceController");
+
+ ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create(
+ R.id.main_content, /* bundle= */ null).start().resume().get();
+
+ List<LifecycleObserver> lifecycleObservers = ReflectionHelpers.getField(
+ fragment.getSettingsLifecycle(), "mObservers");
+ assertThat(lifecycleObservers).isNotNull();
+ assertThat(lifecycleObservers).comparingElementsUsing(instanceOf).contains(true);
+ }
+
+ @Test
+ public void onCreateView_alwaysOnSupported_addControllerToLifeCycleObserver() {
+ setAlwaysOnSupported(true);
+
Correspondence instanceOf = Correspondence.transforming(
observer -> (observer instanceof MagnificationAlwaysOnPreferenceController),
"contains MagnificationAlwaysOnPreferenceController");
@@ -984,6 +1051,11 @@
enabled ? ON : OFF);
}
+ private void setKeyOneFingerPanEnabled(boolean enabled) {
+ Settings.Secure.putInt(mContext.getContentResolver(), KEY_SINGLE_FINGER_PANNING,
+ enabled ? ON : OFF);
+ }
+
private void setAlwaysOnSupported(boolean supported) {
ShadowDeviceConfig.setProperty(
DeviceConfig.NAMESPACE_WINDOW_MANAGER,