Merge changes I502e52f6,Iabf58566,Ida773967,Ic6c48861,If9e5cc6e, ...
* changes:
New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (15/n).
New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (14/n).
New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (13/n).
New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (12/n).
New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (11/n).
New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (10/n).
diff --git a/res/drawable/accessibility_text_reading_reset_button_background.xml b/res/drawable/accessibility_text_reading_reset_button_background.xml
new file mode 100644
index 0000000..b86facf
--- /dev/null
+++ b/res/drawable/accessibility_text_reading_reset_button_background.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:shape="rectangle">
+
+ <corners android:radius="100dp" />
+ <solid android:color="?androidprv:attr/colorAccentPrimary" />
+</shape>
diff --git a/res/layout/accessibility_text_reading_reset_button.xml b/res/layout/accessibility_text_reading_reset_button.xml
new file mode 100644
index 0000000..43800df
--- /dev/null
+++ b/res/layout/accessibility_text_reading_reset_button.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart">
+
+ <Button
+ android:id="@+id/reset_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:background="@drawable/accessibility_text_reading_reset_button_background"
+ android:paddingHorizontal="24dp"
+ android:paddingVertical="14dp"
+ android:text="@string/accessibility_text_reading_reset_button_title"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+</FrameLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0107358..f071f5d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5236,6 +5236,8 @@
<string name="accessibility_text_reading_preview_mail_from">From: bill@email.com</string>
<!-- Content for the mail content of the accessibility text reading preview. [CHAR LIMIT=NONE] -->
<string name="accessibility_text_reading_preview_mail_content">Good morning! Following up on our last conversation, I’d like to check in on the progress of your time machine development plan. Will you be able to have a prototype ready to demo at E3 this year?</string>
+ <!-- Title for the reset button of the accessibility text reading page to reset all preferences state. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_text_reading_reset_button_title">Reset</string>
<!-- Title for the footer text to explain what option accessibility service does. [CHAR LIMIT=35] -->
<string name="accessibility_screen_option">Options</string>
<!-- Summary for the accessibility preference to enable screen magnification. [CHAR LIMIT=25] -->
diff --git a/res/xml/accessibility_text_reading_options.xml b/res/xml/accessibility_text_reading_options.xml
index 4bc9317..7d81565 100644
--- a/res/xml/accessibility_text_reading_options.xml
+++ b/res/xml/accessibility_text_reading_options.xml
@@ -21,16 +21,44 @@
android:persistent="false"
android:title="@string/accessibility_text_reading_options_title">
+ <com.android.settings.accessibility.TextReadingPreviewPreference
+ android:key="preview"
+ android:selectable="false"/>
+
+ <com.android.settings.widget.LabeledSeekBarPreference
+ android:key="font_size"
+ android:selectable="false"
+ android:summary="@string/short_summary_font_size"
+ android:title="@string/title_font_size"
+ settings:iconEnd="@drawable/ic_add_24dp"
+ settings:iconEndContentDescription="@string/font_size_make_larger_desc"
+ settings:iconStart="@drawable/ic_remove_24dp"
+ settings:iconStartContentDescription="@string/font_size_make_smaller_desc"/>
+
+ <com.android.settings.widget.LabeledSeekBarPreference
+ android:key="display_size"
+ android:selectable="false"
+ android:summary="@string/screen_zoom_short_summary"
+ android:title="@string/screen_zoom_title"
+ settings:iconEnd="@drawable/ic_add_24dp"
+ settings:iconEndContentDescription="@string/screen_zoom_make_larger_desc"
+ settings:iconStart="@drawable/ic_remove_24dp"
+ settings:iconStartContentDescription="@string/screen_zoom_make_smaller_desc"/>
+
<SwitchPreference
android:key="toggle_force_bold_text"
android:persistent="false"
android:title="@string/force_bold_text"
- settings:keywords="@string/keywords_bold_text"
- settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
+ settings:keywords="@string/keywords_bold_text" />
<SwitchPreference
android:key="toggle_high_text_contrast_preference"
android:persistent="false"
- android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
- settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
+ android:title="@string/accessibility_toggle_high_text_contrast_preference_title" />
+
+ <com.android.settingslib.widget.LayoutPreference
+ android:key="reset"
+ android:layout="@layout/accessibility_text_reading_reset_button"
+ android:persistent="false"
+ android:selectable="false" />
</PreferenceScreen>
diff --git a/src/com/android/settings/accessibility/DisplaySizeData.java b/src/com/android/settings/accessibility/DisplaySizeData.java
new file mode 100644
index 0000000..42a8c46
--- /dev/null
+++ b/src/com/android/settings/accessibility/DisplaySizeData.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.Display;
+
+import com.android.settingslib.display.DisplayDensityConfiguration;
+import com.android.settingslib.display.DisplayDensityUtils;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+/**
+ * Data class for storing the configurations related to the display size.
+ */
+class DisplaySizeData extends PreviewSizeData<Integer> {
+ DisplaySizeData(Context context) {
+ super(context);
+
+ final DisplayDensityUtils density = new DisplayDensityUtils(getContext());
+ final int initialIndex = density.getCurrentIndex();
+ if (initialIndex < 0) {
+ // Failed to obtain default density, which means we failed to
+ // connect to the window manager service. Just use the current
+ // density and don't let the user change anything.
+ final Resources resources = getContext().getResources();
+ final int densityDpi = resources.getDisplayMetrics().densityDpi;
+ setDefaultValue(densityDpi);
+ setInitialIndex(0);
+ setValues(Collections.singletonList(densityDpi));
+ } else {
+ setDefaultValue(density.getDefaultDensity());
+ setInitialIndex(initialIndex);
+ setValues(Arrays.stream(density.getValues()).boxed().collect(Collectors.toList()));
+ }
+ }
+
+ @Override
+ void commit(int currentProgress) {
+ final int densityDpi = getValues().get(currentProgress);
+ if (densityDpi == getDefaultValue()) {
+ DisplayDensityConfiguration.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY);
+ } else {
+ DisplayDensityConfiguration.setForcedDisplayDensity(Display.DEFAULT_DISPLAY,
+ densityDpi);
+ }
+ }
+}
diff --git a/src/com/android/settings/accessibility/FontSizeData.java b/src/com/android/settings/accessibility/FontSizeData.java
new file mode 100644
index 0000000..1d4f6bd
--- /dev/null
+++ b/src/com/android/settings/accessibility/FontSizeData.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.android.settings.display.ToggleFontSizePreferenceFragment.fontSizeValueToIndex;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import com.android.settings.R;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Data class for storing the configurations related to the font size.
+ */
+final class FontSizeData extends PreviewSizeData<Float> {
+ private static final float FONT_SCALE_DEF_VALUE = 1.0f;
+
+ FontSizeData(Context context) {
+ super(context);
+
+ final Resources resources = getContext().getResources();
+ final ContentResolver resolver = getContext().getContentResolver();
+ final List<String> strEntryValues =
+ Arrays.asList(resources.getStringArray(R.array.entryvalues_font_size));
+ setDefaultValue(FONT_SCALE_DEF_VALUE);
+ final float currentScale =
+ Settings.System.getFloat(resolver, Settings.System.FONT_SCALE, getDefaultValue());
+ setInitialIndex(fontSizeValueToIndex(currentScale, strEntryValues.toArray(new String[0])));
+ setValues(strEntryValues.stream().map(Float::valueOf).collect(Collectors.toList()));
+ }
+
+ @Override
+ void commit(int currentProgress) {
+ final ContentResolver resolver = getContext().getContentResolver();
+ Settings.System.putFloat(resolver, Settings.System.FONT_SCALE,
+ getValues().get(currentProgress));
+ }
+}
diff --git a/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceController.java b/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceController.java
index b59b3b2..e3c1b9e 100644
--- a/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceController.java
+++ b/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceController.java
@@ -24,7 +24,8 @@
import com.android.settings.core.TogglePreferenceController;
/** PreferenceController for displaying all text in bold. */
-public class FontWeightAdjustmentPreferenceController extends TogglePreferenceController {
+public class FontWeightAdjustmentPreferenceController extends TogglePreferenceController implements
+ TextReadingResetController.ResetStateListener {
static final int BOLD_TEXT_ADJUSTMENT =
FontStyle.FONT_WEIGHT_BOLD - FontStyle.FONT_WEIGHT_NORMAL;
@@ -53,4 +54,9 @@
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
+
+ @Override
+ public void resetState() {
+ setChecked(false);
+ }
}
diff --git a/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java b/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
index e98a28c..aad69b9 100644
--- a/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
+++ b/src/com/android/settings/accessibility/HighTextContrastPreferenceController.java
@@ -22,7 +22,11 @@
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
-public class HighTextContrastPreferenceController extends TogglePreferenceController {
+/**
+ * PreferenceController for displaying all text in high contrast style.
+ */
+public class HighTextContrastPreferenceController extends TogglePreferenceController implements
+ TextReadingResetController.ResetStateListener {
public HighTextContrastPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
@@ -49,4 +53,9 @@
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
+
+ @Override
+ public void resetState() {
+ setChecked(false);
+ }
}
diff --git a/src/com/android/settings/accessibility/PreviewSizeData.java b/src/com/android/settings/accessibility/PreviewSizeData.java
new file mode 100644
index 0000000..5d4204e
--- /dev/null
+++ b/src/com/android/settings/accessibility/PreviewSizeData.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
+/**
+ * Abstract data class for storing and fetching the configurations related to the preview of the
+ * text and reading options.
+ */
+abstract class PreviewSizeData<T extends Number> {
+ private final Context mContext;
+ private int mInitialIndex;
+ private T mDefaultValue;
+ private List<T> mValues;
+
+ PreviewSizeData(@NonNull Context context) {
+ mContext = context;
+ }
+
+ Context getContext() {
+ return mContext;
+ }
+
+ List<T> getValues() {
+ return mValues;
+ }
+
+ void setValues(List<T> values) {
+ mValues = values;
+ }
+
+ T getDefaultValue() {
+ return mDefaultValue;
+ }
+
+ void setDefaultValue(T defaultValue) {
+ mDefaultValue = defaultValue;
+ }
+
+ int getInitialIndex() {
+ return mInitialIndex;
+ }
+
+ void setInitialIndex(int initialIndex) {
+ mInitialIndex = initialIndex;
+ }
+
+ /**
+ * Persists the selected size.
+ */
+ abstract void commit(int currentProgress);
+}
diff --git a/src/com/android/settings/accessibility/PreviewSizeSeekBarController.java b/src/com/android/settings/accessibility/PreviewSizeSeekBarController.java
new file mode 100644
index 0000000..c7dfd61
--- /dev/null
+++ b/src/com/android/settings/accessibility/PreviewSizeSeekBarController.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.content.Context;
+import android.widget.SeekBar;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.LabeledSeekBarPreference;
+
+/**
+ * The controller of {@link LabeledSeekBarPreference} that listens to display size and font size
+ * settings changes and updates preview size threshold smoothly.
+ */
+class PreviewSizeSeekBarController extends BasePreferenceController implements
+ TextReadingResetController.ResetStateListener {
+ private final PreviewSizeData<? extends Number> mSizeData;
+ private boolean mSeekByTouch;
+ private ProgressInteractionListener mInteractionListener;
+ private LabeledSeekBarPreference mSeekBarPreference;
+
+ private final SeekBar.OnSeekBarChangeListener mSeekBarChangeListener =
+ new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ mInteractionListener.notifyPreferenceChanged();
+
+ if (!mSeekByTouch && mInteractionListener != null) {
+ mInteractionListener.onProgressChanged();
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ mSeekByTouch = true;
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ mSeekByTouch = false;
+
+ if (mInteractionListener != null) {
+ mInteractionListener.onEndTrackingTouch();
+ }
+ }
+ };
+
+ PreviewSizeSeekBarController(Context context, String preferenceKey,
+ @NonNull PreviewSizeData<? extends Number> sizeData) {
+ super(context, preferenceKey);
+ mSizeData = sizeData;
+ }
+
+ void setInteractionListener(ProgressInteractionListener interactionListener) {
+ mInteractionListener = interactionListener;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+
+ final int dataSize = mSizeData.getValues().size();
+ final int initialIndex = mSizeData.getInitialIndex();
+ mSeekBarPreference = screen.findPreference(getPreferenceKey());
+ mSeekBarPreference.setMax(dataSize - 1);
+ mSeekBarPreference.setProgress(initialIndex);
+ mSeekBarPreference.setContinuousUpdates(true);
+ mSeekBarPreference.setOnSeekBarChangeListener(mSeekBarChangeListener);
+ }
+
+ @Override
+ public void resetState() {
+ final int defaultProgress = mSizeData.getValues().indexOf(mSizeData.getDefaultValue());
+ mSeekBarPreference.setProgress(defaultProgress);
+ }
+
+ /**
+ * Interface for callbacks when users interact with the seek bar.
+ */
+ interface ProgressInteractionListener {
+
+ /**
+ * Called when the progress is changed.
+ */
+ void notifyPreferenceChanged();
+
+ /**
+ * Called when the progress is changed without tracking touch.
+ */
+ void onProgressChanged();
+
+ /**
+ * Called when the seek bar is end tracking.
+ */
+ void onEndTrackingTouch();
+ }
+}
diff --git a/src/com/android/settings/accessibility/TextReadingPreferenceFragment.java b/src/com/android/settings/accessibility/TextReadingPreferenceFragment.java
index 0e8457b..7dd70af 100644
--- a/src/com/android/settings/accessibility/TextReadingPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/TextReadingPreferenceFragment.java
@@ -16,13 +16,21 @@
package com.android.settings.accessibility;
+import static com.android.settings.accessibility.TextReadingResetController.ResetStateListener;
+
import android.app.settings.SettingsEnums;
+import android.content.Context;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
/**
* Accessibility settings for adjusting the system features which are related to the reading. For
* example, bold text, high contrast text, display size, font size and so on.
@@ -30,6 +38,12 @@
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class TextReadingPreferenceFragment extends DashboardFragment {
private static final String TAG = "TextReadingPreferenceFragment";
+ private static final String FONT_SIZE_KEY = "font_size";
+ private static final String DISPLAY_SIZE_KEY = "display_size";
+ private static final String PREVIEW_KEY = "preview";
+ private static final String RESET_KEY = "reset";
+ private static final String BOLD_TEXT_KEY = "toggle_force_bold_text";
+ private static final String HIGHT_TEXT_CONTRAST_KEY = "toggle_high_text_contrast_preference";
@Override
protected int getPreferenceScreenResId() {
@@ -46,6 +60,44 @@
return SettingsEnums.ACCESSIBILITY_TEXT_READING_OPTIONS;
}
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ final FontSizeData fontSizeData = new FontSizeData(context);
+ final DisplaySizeData displaySizeData = new DisplaySizeData(context);
+
+ final TextReadingPreviewController previewController = new TextReadingPreviewController(
+ context, PREVIEW_KEY, fontSizeData, displaySizeData);
+ controllers.add(previewController);
+
+ final PreviewSizeSeekBarController fontSizeController = new PreviewSizeSeekBarController(
+ context, FONT_SIZE_KEY, fontSizeData);
+ fontSizeController.setInteractionListener(previewController);
+ controllers.add(fontSizeController);
+
+ final PreviewSizeSeekBarController displaySizeController = new PreviewSizeSeekBarController(
+ context, DISPLAY_SIZE_KEY, displaySizeData);
+ displaySizeController.setInteractionListener(previewController);
+ controllers.add(displaySizeController);
+
+ final FontWeightAdjustmentPreferenceController fontWeightController =
+ new FontWeightAdjustmentPreferenceController(context, BOLD_TEXT_KEY);
+ controllers.add(fontWeightController);
+
+ final HighTextContrastPreferenceController highTextContrastController =
+ new HighTextContrastPreferenceController(context, HIGHT_TEXT_CONTRAST_KEY);
+ controllers.add(highTextContrastController);
+
+ final List<ResetStateListener> resetStateListeners =
+ controllers.stream().filter(c -> c instanceof ResetStateListener).map(
+ c -> (ResetStateListener) c).collect(Collectors.toList());
+ final TextReadingResetController resetController =
+ new TextReadingResetController(context, RESET_KEY, resetStateListeners);
+ controllers.add(resetController);
+
+ return controllers;
+ }
+
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.accessibility_text_reading_options);
}
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewController.java b/src/com/android/settings/accessibility/TextReadingPreviewController.java
new file mode 100644
index 0000000..cef20aa
--- /dev/null
+++ b/src/com/android/settings/accessibility/TextReadingPreviewController.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.SystemClock;
+import android.view.Choreographer;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.display.PreviewPagerAdapter;
+import com.android.settings.widget.LabeledSeekBarPreference;
+
+import java.util.Objects;
+
+/**
+ * A {@link BasePreferenceController} for controlling the preview pager of the text and reading
+ * options.
+ */
+class TextReadingPreviewController extends BasePreferenceController implements
+ PreviewSizeSeekBarController.ProgressInteractionListener {
+ 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";
+ private static final long MIN_COMMIT_INTERVAL_MS = 800;
+ private static final long CHANGE_BY_SEEKBAR_DELAY_MS = 100;
+ private static final long CHANGE_BY_BUTTON_DELAY_MS = 300;
+ private final FontSizeData mFontSizeData;
+ private final DisplaySizeData mDisplaySizeData;
+ private int mLastFontProgress;
+ private int mLastDisplayProgress;
+ private long mLastCommitTime;
+ private TextReadingPreviewPreference mPreviewPreference;
+ private LabeledSeekBarPreference mFontSizePreference;
+ private LabeledSeekBarPreference mDisplaySizePreference;
+
+ private final Choreographer.FrameCallback mCommit = f -> {
+ tryCommitFontSizeConfig();
+ tryCommitDisplaySizeConfig();
+
+ mLastCommitTime = SystemClock.elapsedRealtime();
+ };
+
+ TextReadingPreviewController(Context context, String preferenceKey,
+ @NonNull FontSizeData fontSizeData, @NonNull DisplaySizeData displaySizeData) {
+ super(context, preferenceKey);
+ mFontSizeData = fontSizeData;
+ mDisplaySizeData = displaySizeData;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+
+ mPreviewPreference = screen.findPreference(PREVIEW_KEY);
+
+ mFontSizePreference = screen.findPreference(FONT_SIZE_KEY);
+ mDisplaySizePreference = screen.findPreference(DISPLAY_SIZE_KEY);
+ Objects.requireNonNull(mFontSizePreference,
+ /* message= */ "Font size preference is null, the preview controller "
+ + "couldn't get the info");
+ Objects.requireNonNull(mDisplaySizePreference,
+ /* message= */ "Display size preference is null, the preview controller"
+ + " couldn't get the info");
+
+ mLastFontProgress = mFontSizePreference.getProgress();
+ mLastDisplayProgress = mDisplaySizePreference.getProgress();
+
+ final Configuration origConfig = mContext.getResources().getConfiguration();
+ final boolean isLayoutRtl =
+ origConfig.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+ final PreviewPagerAdapter pagerAdapter = new PreviewPagerAdapter(mContext, isLayoutRtl,
+ PREVIEW_SAMPLE_RES_IDS, createConfig(origConfig));
+ mPreviewPreference.setPreviewAdapter(pagerAdapter);
+ pagerAdapter.setPreviewLayer(/* newLayerIndex= */ 0,
+ /* currentLayerIndex= */ 0,
+ /* currentFrameIndex= */ 0, /* animate= */ false);
+ }
+
+ @Override
+ public void notifyPreferenceChanged() {
+ final int displayDataSize = mDisplaySizeData.getValues().size();
+ final int fontSizeProgress = mFontSizePreference.getProgress();
+ final int displaySizeProgress = mDisplaySizePreference.getProgress();
+
+ // To be consistent with the
+ // {@link PreviewPagerAdapter#setPreviewLayer(int, int, int, boolean)} behavior,
+ // here also needs the same design. In addition, please also refer to
+ // the {@link #createConfig(Configuration)}.
+ final int pagerIndex = fontSizeProgress * displayDataSize + displaySizeProgress;
+
+ mPreviewPreference.notifyPreviewPagerChanged(pagerIndex);
+ }
+
+ @Override
+ public void onProgressChanged() {
+ postCommitDelayed(CHANGE_BY_BUTTON_DELAY_MS);
+ }
+
+ @Override
+ public void onEndTrackingTouch() {
+ postCommitDelayed(CHANGE_BY_SEEKBAR_DELAY_MS);
+ }
+
+ /**
+ * Avoids the flicker when switching to the previous or next level.
+ *
+ * <p><br>[Flickering problem steps] commit()-> snapshot in framework(old screenshot) ->
+ * app update the preview -> snapshot(old screen) fade out</p>
+ *
+ * <p><br>To prevent flickering problem, we make sure that we update the local preview
+ * first and then we do the commit later. </p>
+ *
+ * <p><br><b>Note:</b> It doesn't matter that we use
+ * Choreographer or main thread handler since the delay time is longer
+ * than 1 frame. Use Choreographer to let developer understand it's a
+ * window update.</p>
+ *
+ * @param commitDelayMs the interval time after a action.
+ */
+ void postCommitDelayed(long commitDelayMs) {
+ if (SystemClock.elapsedRealtime() - mLastCommitTime < MIN_COMMIT_INTERVAL_MS) {
+ commitDelayMs += MIN_COMMIT_INTERVAL_MS;
+ }
+
+ final Choreographer choreographer = Choreographer.getInstance();
+ choreographer.removeFrameCallback(mCommit);
+ choreographer.postFrameCallbackDelayed(mCommit, commitDelayMs);
+ }
+
+ private void tryCommitFontSizeConfig() {
+ final int fontProgress = mFontSizePreference.getProgress();
+ if (fontProgress != mLastFontProgress) {
+ mFontSizeData.commit(fontProgress);
+ mLastFontProgress = fontProgress;
+ }
+ }
+
+ private void tryCommitDisplaySizeConfig() {
+ final int displayProgress = mDisplaySizePreference.getProgress();
+ if (displayProgress != mLastDisplayProgress) {
+ mDisplaySizeData.commit(displayProgress);
+ mLastDisplayProgress = displayProgress;
+ }
+ }
+
+ private Configuration[] createConfig(Configuration origConfig) {
+ final int fontDataSize = mFontSizeData.getValues().size();
+ final int displayDataSize = mDisplaySizeData.getValues().size();
+ final int totalNum = fontDataSize * displayDataSize;
+ final Configuration[] configurations = new Configuration[totalNum];
+
+ for (int i = 0; i < fontDataSize; ++i) {
+ for (int j = 0; j < displayDataSize; ++j) {
+ final Configuration config = new Configuration(origConfig);
+ config.fontScale = mFontSizeData.getValues().get(i);
+ config.densityDpi = mDisplaySizeData.getValues().get(j);
+
+ configurations[i * displayDataSize + j] = config;
+ }
+ }
+
+ return configurations;
+ }
+}
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewPreference.java b/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
index 1b9cc4b..4b8ca39 100644
--- a/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
+++ b/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
@@ -32,8 +32,9 @@
/**
* A {@link Preference} that could show the preview related to the text and reading options.
*/
-final class TextReadingPreviewPreference extends Preference {
+public class TextReadingPreviewPreference extends Preference {
private int mCurrentItem;
+ private int mLastLayerIndex;
private PreviewPagerAdapter mPreviewAdapter;
TextReadingPreviewPreference(Context context) {
@@ -41,7 +42,7 @@
init();
}
- TextReadingPreviewPreference(Context context, AttributeSet attrs) {
+ public TextReadingPreviewPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@@ -120,4 +121,16 @@
private void init() {
setLayoutResource(R.layout.accessibility_text_reading_preview);
}
+
+ void notifyPreviewPagerChanged(int pagerIndex) {
+ Preconditions.checkNotNull(mPreviewAdapter,
+ "Preview adapter is null, you should init the preview adapter first");
+
+ if (pagerIndex != mLastLayerIndex) {
+ mPreviewAdapter.setPreviewLayer(pagerIndex, mLastLayerIndex, getCurrentItem(),
+ /* animate= */ false);
+ }
+
+ mLastLayerIndex = pagerIndex;
+ }
}
diff --git a/src/com/android/settings/accessibility/TextReadingResetController.java b/src/com/android/settings/accessibility/TextReadingResetController.java
new file mode 100644
index 0000000..f4752cb
--- /dev/null
+++ b/src/com/android/settings/accessibility/TextReadingResetController.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.LayoutPreference;
+
+import java.util.List;
+
+/**
+ * The controller of the reset button in the text and reading options page.
+ */
+class TextReadingResetController extends BasePreferenceController {
+ private final List<ResetStateListener> mListeners;
+
+ TextReadingResetController(Context context, String preferenceKey,
+ @NonNull List<ResetStateListener> listeners) {
+ super(context, preferenceKey);
+ mListeners = listeners;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+
+ final LayoutPreference layoutPreference = screen.findPreference(getPreferenceKey());
+ final View view = layoutPreference.findViewById(R.id.reset_button);
+ view.setOnClickListener(v -> mListeners.forEach(ResetStateListener::resetState));
+ }
+
+ /**
+ * Interface for resetting to default state.
+ */
+ interface ResetStateListener {
+ /**
+ * Called when the reset button was clicked.
+ */
+ void resetState();
+ }
+}
diff --git a/src/com/android/settings/display/PreviewPagerAdapter.java b/src/com/android/settings/display/PreviewPagerAdapter.java
index 018be32..693d574 100644
--- a/src/com/android/settings/display/PreviewPagerAdapter.java
+++ b/src/com/android/settings/display/PreviewPagerAdapter.java
@@ -117,7 +117,15 @@
mAnimationEndAction = action;
}
- void setPreviewLayer(int newLayerIndex, int currentLayerIndex, int currentFrameIndex,
+ /**
+ * Switches the sample layouts for the preview pager.
+ *
+ * @param newLayerIndex the new layer index
+ * @param currentLayerIndex the current layer index
+ * @param currentFrameIndex the current frame index
+ * @param animate whether to enable the animation
+ */
+ public void setPreviewLayer(int newLayerIndex, int currentLayerIndex, int currentFrameIndex,
final boolean animate) {
for (FrameLayout previewFrame : mPreviewFrames) {
if (currentLayerIndex >= 0) {
diff --git a/tests/robotests/src/com/android/settings/accessibility/DisplaySizeDataTest.java b/tests/robotests/src/com/android/settings/accessibility/DisplaySizeDataTest.java
new file mode 100644
index 0000000..fabf123
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/DisplaySizeDataTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/**
+ * Tests for {@link DisplaySizeData}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class DisplaySizeDataTest {
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private DisplaySizeData mDisplaySizeData;
+
+ @Before
+ public void setUp() {
+ mDisplaySizeData = new DisplaySizeData(mContext);
+ }
+
+ @Ignore("Ignore it since a NPE is happened in ShadowWindowManagerGlobal. (Ref. b/214161063)")
+ @Test
+ public void commit_success() {
+ final int progress = 4;
+
+ mDisplaySizeData.commit(progress);
+ final float density = mContext.getResources().getDisplayMetrics().density;
+
+ assertThat(density).isEqualTo(mDisplaySizeData.getValues().get(progress));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/FontSizeDataTest.java b/tests/robotests/src/com/android/settings/accessibility/FontSizeDataTest.java
new file mode 100644
index 0000000..7e35714
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/FontSizeDataTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/**
+ * Tests for {@link FontSizeData}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class FontSizeDataTest {
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private FontSizeData mFontSizeData;
+
+ @Before
+ public void setUp() {
+ mFontSizeData = new FontSizeData(mContext);
+ }
+
+ @Test
+ public void commit_success() {
+ final int progress = 3;
+
+ mFontSizeData.commit(progress);
+ final float currentScale =
+ Settings.System.getFloat(mContext.getContentResolver(), Settings.System.FONT_SCALE,
+ /* def= */ 1.0f);
+
+ assertThat(currentScale).isEqualTo(mFontSizeData.getValues().get(progress));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java
new file mode 100644
index 0000000..d33d80e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.widget.LabeledSeekBarPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+/**
+ * Tests for {@link PreviewSizeSeekBarController}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class PreviewSizeSeekBarControllerTest {
+ private static final String FONT_SIZE_KEY = "font_size";
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private PreviewSizeSeekBarController mSeekBarController;
+ private FontSizeData mFontSizeData;
+ private LabeledSeekBarPreference mSeekBarPreference;
+
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mFontSizeData = new FontSizeData(mContext);
+
+ mSeekBarController =
+ new PreviewSizeSeekBarController(mContext, FONT_SIZE_KEY, mFontSizeData);
+
+ mSeekBarPreference = spy(new LabeledSeekBarPreference(mContext, /* attrs= */ null));
+ when(mPreferenceScreen.findPreference(anyString())).thenReturn(mSeekBarPreference);
+ }
+
+ @Test
+ public void initMax_matchResult() {
+ when(mPreferenceScreen.findPreference(anyString())).thenReturn(mSeekBarPreference);
+
+ mSeekBarController.displayPreference(mPreferenceScreen);
+
+ assertThat(mSeekBarPreference.getMax()).isEqualTo(
+ mFontSizeData.getValues().size() - 1);
+ }
+
+ @Test
+ public void initProgress_matchResult() {
+ when(mPreferenceScreen.findPreference(anyString())).thenReturn(mSeekBarPreference);
+
+ mSeekBarController.displayPreference(mPreferenceScreen);
+
+ verify(mSeekBarPreference).setProgress(mFontSizeData.getInitialIndex());
+ }
+
+ @Test
+ public void resetToDefaultState_matchResult() {
+ final int defaultProgress =
+ mFontSizeData.getValues().indexOf(mFontSizeData.getDefaultValue());
+ when(mPreferenceScreen.findPreference(anyString())).thenReturn(mSeekBarPreference);
+
+ mSeekBarController.displayPreference(mPreferenceScreen);
+ mSeekBarPreference.setProgress(defaultProgress + 1);
+ mSeekBarController.resetState();
+
+ assertThat(mSeekBarPreference.getProgress()).isEqualTo(defaultProgress);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java
new file mode 100644
index 0000000..b630509
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.display.PreviewPagerAdapter;
+import com.android.settings.widget.LabeledSeekBarPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowChoreographer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link TextReadingPreviewController}.
+ */
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowChoreographer.class)
+public class TextReadingPreviewControllerTest {
+ 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";
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private TextReadingPreviewController mPreviewController;
+ private TextReadingPreviewPreference mPreviewPreference;
+ private LabeledSeekBarPreference mFontSizePreference;
+ private LabeledSeekBarPreference mDisplaySizePreference;
+
+ @Mock
+ private DisplaySizeData mDisplaySizeData;
+
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ final FontSizeData fontSizeData = new FontSizeData(mContext);
+ final List<Integer> displayData = createFakeDisplayData();
+ when(mDisplaySizeData.getValues()).thenReturn(displayData);
+ mPreviewPreference = spy(new TextReadingPreviewPreference(mContext, /* attr= */ null));
+ mPreviewController = new TextReadingPreviewController(mContext, PREVIEW_KEY, fontSizeData,
+ mDisplaySizeData);
+ mFontSizePreference = new LabeledSeekBarPreference(mContext, /* attr= */ null);
+ mDisplaySizePreference = new LabeledSeekBarPreference(mContext, /* attr= */ null);
+ }
+
+ @Test
+ public void initPreviewerAdapter_verifyAction() {
+ when(mPreferenceScreen.findPreference(PREVIEW_KEY)).thenReturn(mPreviewPreference);
+ when(mPreferenceScreen.findPreference(FONT_SIZE_KEY)).thenReturn(mFontSizePreference);
+ when(mPreferenceScreen.findPreference(DISPLAY_SIZE_KEY)).thenReturn(mDisplaySizePreference);
+
+ mPreviewController.displayPreference(mPreferenceScreen);
+
+ verify(mPreviewPreference).setPreviewAdapter(any(PreviewPagerAdapter.class));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void initPreviewerAdapterWithoutDisplaySizePreference_throwNPE() {
+ when(mPreferenceScreen.findPreference(PREVIEW_KEY)).thenReturn(mPreviewPreference);
+ when(mPreferenceScreen.findPreference(DISPLAY_SIZE_KEY)).thenReturn(mDisplaySizePreference);
+
+ mPreviewController.displayPreference(mPreferenceScreen);
+
+ verify(mPreviewPreference).setPreviewAdapter(any(PreviewPagerAdapter.class));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void initPreviewerAdapterWithoutFontSizePreference_throwNPE() {
+ when(mPreferenceScreen.findPreference(PREVIEW_KEY)).thenReturn(mPreviewPreference);
+ when(mPreferenceScreen.findPreference(FONT_SIZE_KEY)).thenReturn(mFontSizePreference);
+
+ mPreviewController.displayPreference(mPreferenceScreen);
+
+ verify(mPreviewPreference).setPreviewAdapter(any(PreviewPagerAdapter.class));
+ }
+
+ private List<Integer> createFakeDisplayData() {
+ final List<Integer> list = new ArrayList<>();
+ list.add(1);
+ list.add(2);
+ list.add(3);
+ list.add(4);
+
+ return list;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
index 6b9395a..3dc82da 100644
--- a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
@@ -16,8 +16,16 @@
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;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
import android.content.res.Configuration;
import android.view.LayoutInflater;
@@ -50,12 +58,11 @@
@Before
public void setUp() {
final Context context = ApplicationProvider.getApplicationContext();
- final int[] sampleResIds = new int[]{1, 2, 3, 4, 5, 6};
- final Configuration[] configurations = createConfigurations(6);
+ final Configuration[] configurations = createConfigurations(PREVIEW_SAMPLE_RES_IDS.length);
mTextReadingPreviewPreference = new TextReadingPreviewPreference(context);
mPreviewPagerAdapter =
- new PreviewPagerAdapter(context, /* isLayoutRtl= */ false, sampleResIds,
- configurations);
+ spy(new PreviewPagerAdapter(context, /* isLayoutRtl= */ false,
+ PREVIEW_SAMPLE_RES_IDS, configurations));
final LayoutInflater inflater = LayoutInflater.from(context);
final View view =
inflater.inflate(mTextReadingPreviewPreference.getLayoutResource(),
@@ -87,7 +94,7 @@
@Test
public void setCurrentItem_success() {
- final int currentItem = 3;
+ final int currentItem = 1;
mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
mTextReadingPreviewPreference.onBindViewHolder(mHolder);
@@ -104,6 +111,24 @@
mTextReadingPreviewPreference.setCurrentItem(currentItem);
}
+ @Test(expected = NullPointerException.class)
+ public void updatePagerWithoutPreviewAdapter_throwNPE() {
+ final int index = 1;
+
+ mTextReadingPreviewPreference.notifyPreviewPagerChanged(index);
+ }
+
+ @Test
+ public void notifyPreviewPager_setPreviewLayer() {
+ final int index = 2;
+ mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
+ mTextReadingPreviewPreference.onBindViewHolder(mHolder);
+
+ mTextReadingPreviewPreference.notifyPreviewPagerChanged(index);
+
+ verify(mPreviewPagerAdapter).setPreviewLayer(eq(index), anyInt(), anyInt(), anyBoolean());
+ }
+
private static Configuration[] createConfigurations(int count) {
final Configuration[] configurations = new Configuration[count];
for (int i = 0; i < count; i++) {
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingResetControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingResetControllerTest.java
new file mode 100644
index 0000000..2ae8e24
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingResetControllerTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.android.settings.accessibility.TextReadingResetController.ResetStateListener;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.LayoutPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link TextReadingResetController}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class TextReadingResetControllerTest {
+ private static final String TEST_KEY = "test";
+ private static final String RESET_KEY = "reset";
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private final View mResetView = new View(mContext);
+ private final List<ResetStateListener> mListeners = new ArrayList<>();
+ private TextReadingResetController mResetController;
+ private TestPreferenceController mPreferenceController;
+
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ @Mock
+ private LayoutPreference mLayoutPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mPreferenceController = new TestPreferenceController(mContext, TEST_KEY);
+ mListeners.add(mPreferenceController);
+ mResetController = new TextReadingResetController(mContext, RESET_KEY, mListeners);
+ }
+
+ @Test
+ public void setClickListener_success() {
+ setupResetButton();
+
+ mResetController.displayPreference(mPreferenceScreen);
+
+ assertThat(mResetView.hasOnClickListeners()).isTrue();
+ }
+
+ @Test
+ public void triggerResetState_success() {
+ setupResetButton();
+
+ mResetController.displayPreference(mPreferenceScreen);
+ mResetView.callOnClick();
+
+ assertThat(mPreferenceController.isReset()).isTrue();
+ }
+
+ private void setupResetButton() {
+ when(mPreferenceScreen.findPreference(RESET_KEY)).thenReturn(mLayoutPreference);
+ when(mLayoutPreference.findViewById(R.id.reset_button)).thenReturn(mResetView);
+ }
+
+ private static class TestPreferenceController extends BasePreferenceController implements
+ ResetStateListener {
+ private boolean mIsReset = false;
+
+ TestPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ @Override
+ public void resetState() {
+ mIsReset = true;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ boolean isReset() {
+ return mIsReset;
+ }
+ }
+}
diff --git a/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java
index 7f4048d..e3d2408 100644
--- a/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java
@@ -31,6 +31,9 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+/**
+ * Tests for {@link FontWeightAdjustmentPreferenceController}.
+ */
@RunWith(AndroidJUnit4.class)
public class FontWeightAdjustmentPreferenceControllerTest {
private static final int ON = FontWeightAdjustmentPreferenceController.BOLD_TEXT_ADJUSTMENT;
@@ -91,4 +94,14 @@
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FONT_WEIGHT_ADJUSTMENT, OFF)).isEqualTo(OFF);
}
+
+ @Test
+ public void resetState_shouldDisableBoldText() {
+ mController.setChecked(true);
+
+ mController.resetState();
+
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.FONT_WEIGHT_ADJUSTMENT, OFF)).isEqualTo(OFF);
+ }
}
diff --git a/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
index 6250fef..1ada051 100644
--- a/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java
@@ -31,6 +31,9 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+/**
+ * Tests for {@link HighTextContrastPreferenceController}.
+ */
@RunWith(AndroidJUnit4.class)
public class HighTextContrastPreferenceControllerTest {
@@ -93,4 +96,14 @@
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, UNKNOWN)).isEqualTo(OFF);
}
+
+ @Test
+ public void resetState_shouldDisableTextContrast() {
+ mController.setChecked(true);
+
+ mController.resetState();
+
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, UNKNOWN)).isEqualTo(OFF);
+ }
}