From 2f1a7d6155c9798128345e0290c05bcec33aff56 Mon Sep 17 00:00:00 2001 From: Roy Chou Date: Wed, 12 Jun 2024 09:12:37 +0000 Subject: [PATCH] chore(onefingerpan): update onefingerpan preference summary and magnification settings page footer description Based on b/338409557#comment5, we update the onefingerpan toggle's summary, and make the magnification settings page's footer HTML description be dynamic based on one finger panning preference state. Bug: 338409557 Flag: com.android.server.accessibility.enable_magnification_one_finger_panning_gesture Test: manually atest MagnificationOneFingerPanningPreferenceControllerTest atest ToggleScreenMagnificationPreferenceFragmentTest atest ToggleFeaturePreferenceFragmentTest Change-Id: I817cad4fb0c034bcd2db0485ca27c30ea88a0280 --- res/values/strings.xml | 30 ++++++++- ...nOneFingerPanningPreferenceController.java | 15 ++--- .../ToggleFeaturePreferenceFragment.java | 31 ++++++--- ...ScreenMagnificationPreferenceFragment.java | 42 ++++++++++-- ...FingerPanningPreferenceControllerTest.java | 19 ++---- ...enMagnificationPreferenceFragmentTest.java | 65 ++++++++++++++++++- 6 files changed, 162 insertions(+), 40 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index f92fd2aca84..80450580a4e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4841,8 +4841,10 @@ Cancel Magnification settings - - One-finger panning + + Move magnifier with 1 finger + + Drag 1 finger to move around the screen Move the magnification area by dragging one finger. @@ -4906,6 +4908,30 @@ {4,number,integer}. Lift finger to stop magnification ]]> + + + To zoom in:
+ {0,number,integer}. Use shortcut to start magnification
+ {1,number,integer}. Tap the screen
+ {2,number,integer}. Drag 2 fingers to move around the screen
+ {3,number,integer}. Pinch with 2 fingers to adjust zoom
+ {4,number,integer}. Use shortcut to stop magnification

+ You can also zoom in temporarily and more. + ]]> +
+ + + To zoom in:
+ {0,number,integer}. Use shortcut to start magnification
+ {1,number,integer}. Tap the screen
+ {2,number,integer}. Drag 1 or 2 fingers to move around the screen
+ {3,number,integer}. Pinch with 2 fingers to adjust zoom
+ {4,number,integer}. Use shortcut to stop magnification

+ You can also zoom in temporarily and more. + ]]> +
When magnification is turned on, you can zoom in on your screen.\n\nTo zoom, start magnification, then tap anywhere on the screen.\n\n\nTo zoom temporarily, start magnification, then touch & hold anywhere on the screen.\n\n\nYou can’t zoom in on the keyboard or navigation bar. diff --git a/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java b/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java index 3e3b8d907df..a6d87f268e6 100644 --- a/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java +++ b/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java @@ -28,6 +28,7 @@ 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; @@ -103,16 +104,10 @@ public class MagnificationOneFingerPanningPreferenceController extends @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) - : mContext.getString( - R.string.accessibility_magnification_one_finger_panning_summary_off); + @StringRes int resId = mSwitchPreference.isEnabled() + ? R.string.accessibility_magnification_one_finger_panning_summary + : R.string.accessibility_magnification_one_finger_panning_summary_unavailable; + return mContext.getString(resId); } @Override diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index a57b4591240..e4d7925d82b 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -101,6 +101,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment protected SettingsMainSwitchPreference mToggleServiceSwitchPreference; protected ShortcutPreference mShortcutPreference; protected Preference mSettingsPreference; + @Nullable protected AccessibilityFooterPreference mHtmlFooterPreference; protected AccessibilityFooterPreferenceController mFooterPreferenceController; protected String mPreferenceKey; protected Dialog mDialog; @@ -589,27 +590,40 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment } private void initHtmlTextPreference() { - if (TextUtils.isEmpty(mHtmlDescription)) { + if (TextUtils.isEmpty(getCurrentHtmlDescription())) { return; } final PreferenceScreen screen = getPreferenceScreen(); - final CharSequence htmlDescription = Html.fromHtml(mHtmlDescription.toString(), - Html.FROM_HTML_MODE_COMPACT, mImageGetter, /* tagHandler= */ null); - final AccessibilityFooterPreference htmlFooterPreference = + mHtmlFooterPreference = new AccessibilityFooterPreference(screen.getContext()); - htmlFooterPreference.setKey(KEY_HTML_DESCRIPTION_PREFERENCE); - htmlFooterPreference.setSummary(htmlDescription); - screen.addPreference(htmlFooterPreference); + mHtmlFooterPreference.setKey(KEY_HTML_DESCRIPTION_PREFERENCE); + updateHtmlTextPreference(); + screen.addPreference(mHtmlFooterPreference); // TODO(b/171272809): Migrate to DashboardFragment. final String title = getString(R.string.accessibility_introduction_title, mPackageName); mFooterPreferenceController = new AccessibilityFooterPreferenceController( - screen.getContext(), htmlFooterPreference.getKey()); + screen.getContext(), mHtmlFooterPreference.getKey()); mFooterPreferenceController.setIntroductionTitle(title); mFooterPreferenceController.displayPreference(screen); } + protected void updateHtmlTextPreference() { + if (mHtmlFooterPreference == null) { + return; + } + + String description = getCurrentHtmlDescription().toString(); + final CharSequence htmlDescription = Html.fromHtml(description, + Html.FROM_HTML_MODE_COMPACT, mImageGetter, /* tagHandler= */ null); + mHtmlFooterPreference.setSummary(htmlDescription); + } + + CharSequence getCurrentHtmlDescription() { + return mHtmlDescription; + } + private void initFooterPreference() { if (!TextUtils.isEmpty(mDescription)) { createFooterPreference(getPreferenceScreen(), mDescription, @@ -617,7 +631,6 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment } } - /** * Creates {@link AccessibilityFooterPreference} and append into {@link PreferenceScreen} * diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index fc75cded3d1..b1ad7f782d3 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -45,6 +45,7 @@ import android.view.accessibility.AccessibilityManager.TouchExplorationStateChan import android.widget.CheckBox; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.SwitchPreferenceCompat; @@ -91,6 +92,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends @Nullable private CheckBox mTwoFingerTripleTapTypeCheckBox; private DialogCreatable mDialogDelegate; + @Nullable + MagnificationOneFingerPanningPreferenceController mOneFingerPanningPreferenceController; + private boolean mInSetupWizard; @Override @@ -236,7 +240,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends context.getString(R.string.accessibility_screen_magnification_intro_text)); } - if (!arguments.containsKey(AccessibilitySettings.EXTRA_HTML_DESCRIPTION)) { + if (!arguments.containsKey(AccessibilitySettings.EXTRA_HTML_DESCRIPTION) + && !Flags.enableMagnificationOneFingerPanningGesture()) { String summary = MessageFormat.format( context.getString(R.string.accessibility_screen_magnification_summary), new Object[]{1, 2, 3, 4, 5}); @@ -308,12 +313,12 @@ public class ToggleScreenMagnificationPreferenceFragment extends MagnificationOneFingerPanningPreferenceController.PREF_KEY); generalCategory.addPreference(oneFingerPanningPreference); - var oneFingerPanningPreferenceController = + mOneFingerPanningPreferenceController = new MagnificationOneFingerPanningPreferenceController(getContext()); - oneFingerPanningPreferenceController.setInSetupWizard(mInSetupWizard); - getSettingsLifecycle().addObserver(oneFingerPanningPreferenceController); - oneFingerPanningPreferenceController.displayPreference(getPreferenceScreen()); - addPreferenceController(oneFingerPanningPreferenceController); + mOneFingerPanningPreferenceController.setInSetupWizard(mInSetupWizard); + getSettingsLifecycle().addObserver(mOneFingerPanningPreferenceController); + mOneFingerPanningPreferenceController.displayPreference(getPreferenceScreen()); + addPreferenceController(mOneFingerPanningPreferenceController); } private void addJoystickSetting(PreferenceCategory generalCategory) { @@ -471,6 +476,12 @@ public class ToggleScreenMagnificationPreferenceFragment extends ); contentObserver.registerKeysToObserverCallback(keysToObserve, key -> updatePreferencesState()); + + if (Flags.enableMagnificationOneFingerPanningGesture()) { + contentObserver.registerKeysToObserverCallback( + List.of(Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED), + key -> updateHtmlTextPreference()); + } } private void updatePreferencesState() { @@ -480,6 +491,25 @@ public class ToggleScreenMagnificationPreferenceFragment extends findPreference(controller.getPreferenceKey()))); } + @Override + CharSequence getCurrentHtmlDescription() { + CharSequence origin = super.getCurrentHtmlDescription(); + if (!TextUtils.isEmpty(origin)) { + // If in ToggleFeaturePreferenceFragment we already have a fixed html description, we + // should use the fixed one, otherwise we'll dynamically decide the description. + return origin; + } + + Context context = getContext(); + if (mOneFingerPanningPreferenceController != null && context != null) { + @StringRes int resId = mOneFingerPanningPreferenceController.isChecked() + ? R.string.accessibility_screen_magnification_summary_one_finger_panning_on + : R.string.accessibility_screen_magnification_summary_one_finger_panning_off; + return MessageFormat.format(context.getString(resId), new Object[]{1, 2, 3, 4, 5}); + } + return ""; + } + @Override protected List getShortcutFeatureSettingsKeys() { final List shortcutKeys = super.getShortcutFeatureSettingsKeys(); diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java index 8b4bcd8fe47..9f501466cfb 100644 --- a/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java @@ -133,23 +133,23 @@ public class MagnificationOneFingerPanningPreferenceControllerTest { } @Test - public void getSummary_switchModeAndSettingsOff_disabledSummaryTextUsed() { + public void getSummary_switchModeAndSettingsOff_defaultSummaryTextUsed() { MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL); Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, OFF); mController.updateState(mSwitchPreference); - assertThat(mController.getSummary()).isEqualTo(disabledSummary()); + assertThat(mController.getSummary().toString()).isEqualTo(defaultSummary()); } @Test - public void getSummary_switchModeAndSettingsOn_enabledSummaryTextUsed() { + public void getSummary_switchModeAndSettingsOn_defaultSummaryTextUsed() { MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL); Settings.Secure.putInt(mContext.getContentResolver(), ONE_FINGER_PANNING_KEY, ON); mController.updateState(mSwitchPreference); - assertThat(mController.getSummary()).isEqualTo(enabledSummary()); + assertThat(mController.getSummary().toString()).isEqualTo(defaultSummary()); } @Test @@ -158,7 +158,7 @@ public class MagnificationOneFingerPanningPreferenceControllerTest { mController.updateState(mSwitchPreference); - assertThat(mController.getSummary()).isEqualTo(unavailableSummary()); + assertThat(mController.getSummary().toString()).isEqualTo(unavailableSummary()); } @Test @@ -199,14 +199,9 @@ public class MagnificationOneFingerPanningPreferenceControllerTest { assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); } - private String enabledSummary() { + private String defaultSummary() { return mContext.getString( - R.string.accessibility_magnification_one_finger_panning_summary_on); - } - - private String disabledSummary() { - return mContext.getString( - R.string.accessibility_magnification_one_finger_panning_summary_off); + R.string.accessibility_magnification_one_finger_panning_summary); } private String unavailableSummary() { diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java index ab2e9d1a121..b8015211e6d 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragmentTest.java @@ -24,6 +24,7 @@ import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; @@ -393,6 +394,40 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { Settings.Secure.ACCESSIBILITY_QS_TARGETS))).hasSize(0); } + @Test + @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) + public void onResume_oneFingerPanningFlagOn_registerToSpecificUri() { + ShadowContentResolver shadowContentResolver = Shadows.shadowOf( + mContext.getContentResolver()); + Uri observedUri = Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED); + // verify no one finger panning settings observer registered before launching the fragment + assertThat(shadowContentResolver.getContentObservers(observedUri)).isEmpty(); + + mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); + + Collection observers = + shadowContentResolver.getContentObservers(observedUri); + assertThat(observers.size()).isEqualTo(1); + assertThat(observers.stream().findFirst().get()).isInstanceOf( + AccessibilitySettingsContentObserver.class); + } + + @Test + @DisableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) + public void onResume_oneFingerPanningFlagOff_notRegisterToSpecificUri() { + ShadowContentResolver shadowContentResolver = Shadows.shadowOf( + mContext.getContentResolver()); + Uri observedUri = Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED); + // verify no one finger panning settings observer registered before launching the fragment + assertThat(shadowContentResolver.getContentObservers(observedUri)).isEmpty(); + + mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); + // verify no one finger panning settings observer registered after launching the fragment + assertThat(shadowContentResolver.getContentObservers(observedUri)).isEmpty(); + } + @Test public void hasValueInSettings_putValue_hasValue() { setMagnificationTripleTapEnabled(/* enabled= */ true); @@ -934,7 +969,9 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { } @Test - public void onProcessArguments_defaultArgumentUnavailable_shouldSetDefaultArguments() { + @DisableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) + public void + onProcessArguments_defaultArgumentUnavailableAndFlagOff_shouldSetDefaultArguments() { ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create( R.id.main_content, /* bundle= */ null).start().resume().get(); @@ -947,6 +984,32 @@ public class ToggleScreenMagnificationPreferenceFragmentTest { assertTrue(arguments.containsKey(AccessibilitySettings.EXTRA_HTML_DESCRIPTION)); } + @Test + @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) + public void + onProcessArguments_defaultArgumentUnavailableAndFlagOn_shouldSetDefaultArguments() { + ToggleScreenMagnificationPreferenceFragment fragment = + mFragController.create( + R.id.main_content, /* bundle= */ null).start().resume().get(); + Bundle arguments = new Bundle(); + + fragment.onProcessArguments(arguments); + + assertTrue(arguments.containsKey(AccessibilitySettings.EXTRA_PREFERENCE_KEY)); + assertTrue(arguments.containsKey(AccessibilitySettings.EXTRA_INTRO)); + // If OneFingerPanning flag is on, the EXTRA_HTML_DESCRIPTION should not be set. The html + // description would be decided dynamically based on the OneFingerPanning preference state. + assertFalse(arguments.containsKey(AccessibilitySettings.EXTRA_HTML_DESCRIPTION)); + } + + @Test + public void getCurrentHtmlDescription_shouldNotBeEmpty() { + ToggleScreenMagnificationPreferenceFragment fragment = + mFragController.create( + R.id.main_content, /* bundle= */ null).start().resume().get(); + assertThat(fragment.getCurrentHtmlDescription().toString()).isNotEmpty(); + } + @Test public void getSummary_magnificationEnabled_returnShortcutOnWithSummary() { setMagnificationTripleTapEnabled(true);