Merge "chore(onefingerpan): update onefingerpan preference summary and magnification settings page footer description" into main
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fbb3417..a490856 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4883,8 +4883,10 @@
     <string name="accessibility_magnification_triple_tap_warning_negative_button">Cancel</string>
     <!-- Title for the accessibility preference screen to enable screen magnification settings. [CHAR LIMIT=35] -->
     <string name="accessibility_magnification_service_settings_title">Magnification settings</string>
-    <!-- Title for accessibility magnification preference where user can move the magnification area by dragging one finger instead of two. [CHAR LIMIT=60] -->
-    <string name="accessibility_magnification_one_finger_panning_title">One-finger panning</string>
+    <!-- Title for accessibility magnification preference where user can move the magnification area by dragging one finger. [CHAR LIMIT=60] -->
+    <string name="accessibility_magnification_one_finger_panning_title">Move magnifier with 1 finger</string>
+    <!-- Summary for accessibility magnification one finger panning feature where user can move the magnification area by dragging one finger. [CHAR LIMIT=60] -->
+    <string name="accessibility_magnification_one_finger_panning_summary">Drag 1 finger to move around the screen</string>
     <!-- Summary for accessibility magnification preference when one finger panning feature is turned on.
          The feature when enabled allows user to move the magnification area by dragging one finger instead of two. [CHAR LIMIT=60] -->
     <string name="accessibility_magnification_one_finger_panning_summary_on">Move the magnification area by dragging one finger.</string>
@@ -4948,6 +4950,30 @@
         {4,number,integer}. Lift finger to stop magnification
         ]]>
     </string>
+    <!-- Instructions on the accessibility preference screen teaching the user how to interact with screen magnification when one finger panning feature is turned off. [CHAR LIMIT=none] -->
+    <string name="accessibility_screen_magnification_summary_one_finger_panning_off">
+        <![CDATA[
+        <b>To zoom in:</b><br/>
+        {0,number,integer}. Use shortcut to start magnification<br/>
+        {1,number,integer}. Tap the screen<br/>
+        {2,number,integer}. Drag 2 fingers to move around the screen<br/>
+        {3,number,integer}. Pinch with 2 fingers to adjust zoom<br/>
+        {4,number,integer}. Use shortcut to stop magnification<br/><br/>
+        You can also zoom in temporarily and more.
+        ]]>
+    </string>
+    <!-- Instructions on the accessibility preference screen teaching the user how to interact with screen magnification when one finger panning feature is turned on. [CHAR LIMIT=none] -->
+    <string name="accessibility_screen_magnification_summary_one_finger_panning_on">
+        <![CDATA[
+        <b>To zoom in:</b><br/>
+        {0,number,integer}. Use shortcut to start magnification<br/>
+        {1,number,integer}. Tap the screen<br/>
+        {2,number,integer}. Drag 1 or 2 fingers to move around the screen<br/>
+        {3,number,integer}. Pinch with 2 fingers to adjust zoom<br/>
+        {4,number,integer}. Use shortcut to stop magnification<br/><br/>
+        You can also zoom in temporarily and more.
+        ]]>
+    </string>
     <!-- Summary for the accessibility preference screen to enable screen magnification via the nav bar. [CHAR LIMIT=none] -->
     <string name="accessibility_screen_magnification_navbar_summary">When magnification is turned on, you can zoom in on your screen.\n\n<b>To zoom</b>, start magnification, then tap anywhere on the screen.\n<ul><li>Drag 2 or more fingers to scroll</li>\n<li>Pinch 2 or more fingers to adjust zoom</li></ul>\n\n<b>To zoom temporarily</b>, start magnification, then touch &amp; hold anywhere on the screen.\n<ul><li>Drag to move around the screen</li>\n<li>Lift finger to zoom out</li></ul>\n\nYou can’t zoom in on the keyboard or navigation bar.</string>
     <!-- Accessibility label for paging indicator in accessibility tutorial page. [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java b/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java
index 3e3b8d9..a6d87f2 100644
--- a/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceController.java
@@ -28,6 +28,7 @@
 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 @@
 
     @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 a57b459..e4d7925 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -101,6 +101,7 @@
     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 @@
     }
 
     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 @@
         }
     }
 
-
     /**
      * 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 fc75cde..b1ad7f7 100644
--- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java
@@ -45,6 +45,7 @@
 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 @@
     @Nullable private CheckBox mTwoFingerTripleTapTypeCheckBox;
     private DialogCreatable mDialogDelegate;
 
+    @Nullable
+    MagnificationOneFingerPanningPreferenceController mOneFingerPanningPreferenceController;
+
     private boolean mInSetupWizard;
 
     @Override
@@ -236,7 +240,8 @@
                     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 @@
                 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 @@
         );
         contentObserver.registerKeysToObserverCallback(keysToObserve,
                 key -> updatePreferencesState());
+
+        if (Flags.enableMagnificationOneFingerPanningGesture()) {
+            contentObserver.registerKeysToObserverCallback(
+                    List.of(Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED),
+                    key -> updateHtmlTextPreference());
+        }
     }
 
     private void updatePreferencesState() {
@@ -481,6 +492,25 @@
     }
 
     @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<String> getShortcutFeatureSettingsKeys() {
         final List<String> shortcutKeys = super.getShortcutFeatureSettingsKeys();
         shortcutKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationOneFingerPanningPreferenceControllerTest.java
index 8b4bcd8..9f50146 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 @@
     }
 
     @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 @@
 
         mController.updateState(mSwitchPreference);
 
-        assertThat(mController.getSummary()).isEqualTo(unavailableSummary());
+        assertThat(mController.getSummary().toString()).isEqualTo(unavailableSummary());
     }
 
     @Test
@@ -199,14 +199,9 @@
         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 ab2e9d1..b801521 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.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;
@@ -394,6 +395,40 @@
     }
 
     @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<ContentObserver> 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 @@
     }
 
     @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();
@@ -948,6 +985,32 @@
     }
 
     @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);