Customize the text reading preview layouts

Make it possible to customize the available text reading preview
layouts through overlays.

Bug: 307481249
Test: make RunSettingsRoboTests ROBOTEST_FILTER=
"com.android.settings.accessibility.TextReadingPreviewPreferenceTest"
(cherry picked from https://android-review.googlesource.com/q/commit:2a7da9c433f57db9b7b9ad5c54bddb5da81e5693)
Change-Id: I3e55eeb7545a4d5d1f689ab4160e453996b58bdb
diff --git a/aconfig/settings_accessibility_flag_declarations.aconfig b/aconfig/settings_accessibility_flag_declarations.aconfig
index 4363bfc..10b536d 100644
--- a/aconfig/settings_accessibility_flag_declarations.aconfig
+++ b/aconfig/settings_accessibility_flag_declarations.aconfig
@@ -6,6 +6,13 @@
 # flags with 'accessibility' to prevent naming collision.
 
 flag {
+  name: "accessibility_customize_text_reading_preview"
+  namespace: "accessibility"
+  description: "Pulls the accessibility text-reading preview pages from a config."
+  bug: "307481249"
+}
+
+flag {
   name: "accessibility_show_app_info_button"
   namespace: "accessibility"
   description: "Shows an 'app info' button on non-framework a11y Service and Activity pages."
diff --git a/res/values/config.xml b/res/values/config.xml
index 4eba076..443f815 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -765,4 +765,11 @@
 
     <!-- Allowed packages to show the confirmation dialog for a system locale suggestion  -->
     <string-array name="allowed_packages_for_locale_confirmation_diallog" translatable="false"/>
+
+    <!-- Array of text reading preview layouts. Must contain at least 1 layout -->
+    <array name="config_text_reading_preview_samples">
+        <item>@layout/accessibility_text_reading_preview_app_grid</item>
+        <item>@layout/screen_zoom_preview_1</item>
+        <item>@layout/accessibility_text_reading_preview_mail_content</item>
+    </array>
 </resources>
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewController.java b/src/com/android/settings/accessibility/TextReadingPreviewController.java
index ffa156b..4ec0b3d 100644
--- a/src/com/android/settings/accessibility/TextReadingPreviewController.java
+++ b/src/com/android/settings/accessibility/TextReadingPreviewController.java
@@ -18,12 +18,14 @@
 
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.TypedArray;
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.Choreographer;
 import android.view.View;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
@@ -31,6 +33,7 @@
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.instrumentation.SettingsStatsLog;
 import com.android.settings.display.PreviewPagerAdapter;
+import com.android.settings.flags.Flags;
 import com.android.settings.widget.LabeledSeekBarPreference;
 
 import java.util.Objects;
@@ -44,11 +47,10 @@
     private static final String TAG = "TextReadingPreviewCtrl";
     private static final int LAYER_INITIAL_INDEX = 0;
     private static final int FRAME_INITIAL_INDEX = 0;
-    static final int[] PREVIEW_SAMPLE_RES_IDS = new int[]{
+    private static final int[] PREVIEW_SAMPLE_RES_IDS = new int[]{
             R.layout.accessibility_text_reading_preview_app_grid,
             R.layout.screen_zoom_preview_1,
             R.layout.accessibility_text_reading_preview_mail_content};
-
     private static final String PREVIEW_KEY = "preview";
     private static final String FONT_SIZE_KEY = "font_size";
     private static final String DISPLAY_SIZE_KEY = "display_size";
@@ -107,11 +109,12 @@
         final Configuration origConfig = mContext.getResources().getConfiguration();
         final boolean isLayoutRtl =
                 origConfig.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        final int[] previewSamples = getPreviewSampleLayouts(mContext);
         final PreviewPagerAdapter pagerAdapter = new PreviewPagerAdapter(mContext, isLayoutRtl,
-                PREVIEW_SAMPLE_RES_IDS, createConfig(origConfig));
+                previewSamples, createConfig(origConfig));
         mPreviewPreference.setPreviewAdapter(pagerAdapter);
         mPreviewPreference.setCurrentItem(
-                isLayoutRtl ? PREVIEW_SAMPLE_RES_IDS.length - 1 : FRAME_INITIAL_INDEX);
+                isLayoutRtl ? previewSamples.length - 1 : FRAME_INITIAL_INDEX);
 
         final int initialPagerIndex =
                 mLastFontProgress * mDisplaySizeData.getValues().size() + mLastDisplayProgress;
@@ -178,6 +181,22 @@
         choreographer.postFrameCallbackDelayed(mCommit, commitDelayMs);
     }
 
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    static int[] getPreviewSampleLayouts(Context context) {
+        if (!Flags.accessibilityCustomizeTextReadingPreview()) {
+            return PREVIEW_SAMPLE_RES_IDS;
+        }
+        TypedArray previews = context.getResources().obtainTypedArray(
+                R.array.config_text_reading_preview_samples);
+        int previewCount = previews.length();
+        int[] previewSamples = new int[previewCount];
+        for (int i = 0; i < previewCount; i++) {
+            previewSamples[i] = previews.getResourceId(i, R.layout.screen_zoom_preview_1);
+        }
+        previews.recycle();
+        return previewSamples;
+    }
+
     private int getPagerIndex() {
         final int displayDataSize = mDisplaySizeData.getValues().size();
         final int fontSizeProgress = mFontSizePreference.getProgress();
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
index 1688142..0162d26 100644
--- a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.accessibility;
 
-import static com.android.settings.accessibility.TextReadingPreviewController.PREVIEW_SAMPLE_RES_IDS;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -39,6 +37,7 @@
 import com.android.settings.R;
 import com.android.settings.display.PreviewPagerAdapter;
 
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -54,15 +53,18 @@
     private PreferenceViewHolder mHolder;
     private ViewPager mViewPager;
     private PreviewPagerAdapter mPreviewPagerAdapter;
+    private int mPreviewSampleCount;
 
     @Before
     public void setUp() {
         final Context context = ApplicationProvider.getApplicationContext();
-        final Configuration[] configurations = createConfigurations(PREVIEW_SAMPLE_RES_IDS.length);
+        final int[] previewSamples = TextReadingPreviewController.getPreviewSampleLayouts(context);
+        mPreviewSampleCount = previewSamples.length;
+        final Configuration[] configurations = createConfigurations(mPreviewSampleCount);
         mTextReadingPreviewPreference = new TextReadingPreviewPreference(context);
         mPreviewPagerAdapter =
                 spy(new PreviewPagerAdapter(context, /* isLayoutRtl= */ false,
-                        PREVIEW_SAMPLE_RES_IDS, configurations));
+                        previewSamples, configurations));
         final LayoutInflater inflater = LayoutInflater.from(context);
         final View view =
                 inflater.inflate(mTextReadingPreviewPreference.getLayoutResource(),
@@ -81,7 +83,7 @@
 
     @Test
     public void setPreviewAdapterWithNull_resetCurrentItem() {
-        final int currentItem = 2;
+        final int currentItem = mPreviewSampleCount - 1;
         mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
         mTextReadingPreviewPreference.setCurrentItem(currentItem);
         mTextReadingPreviewPreference.onBindViewHolder(mHolder);
@@ -94,7 +96,7 @@
 
     @Test
     public void setCurrentItem_success() {
-        final int currentItem = 1;
+        final int currentItem = mPreviewSampleCount - 1;
         mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
         mTextReadingPreviewPreference.onBindViewHolder(mHolder);
 
@@ -106,21 +108,25 @@
 
     @Test(expected = NullPointerException.class)
     public void setCurrentItemBeforeSetPreviewAdapter_throwNPE() {
-        final int currentItem = 5;
+        final int currentItem = mPreviewSampleCount + 2;
 
         mTextReadingPreviewPreference.setCurrentItem(currentItem);
     }
 
     @Test(expected = NullPointerException.class)
     public void updatePagerWithoutPreviewAdapter_throwNPE() {
-        final int index = 1;
+        final int index = mPreviewSampleCount - 1;
 
         mTextReadingPreviewPreference.notifyPreviewPagerChanged(index);
     }
 
     @Test
     public void notifyPreviewPager_setPreviewLayer() {
-        final int index = 2;
+        // The preview pager cannot switch page if there is only one preview layout, so skip the
+        // test if so
+        Assume.assumeTrue(mPreviewSampleCount > 1);
+
+        final int index = mPreviewSampleCount - 1;
         mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
         mTextReadingPreviewPreference.onBindViewHolder(mHolder);
 
@@ -131,7 +137,7 @@
 
     @Test
     public void afterPagerChange_updateCurrentItem() {
-        final int currentItem = 2;
+        final int currentItem = mPreviewSampleCount - 1;
         mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
         mTextReadingPreviewPreference.onBindViewHolder(mHolder);