New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (13/n).

- Add the ResetPreference for controlling all preferences state in the text and reading options page.
1) Create a new interface ResetStateListener for the other preferences.

- Link-up between the reset, font size, and display size preferences.

Bug: 211503117
Test: make RunSettingsRoboTests ROBOTEST_FILTER=PreviewSizeSeekBarControllerTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=TextReadingResetControllerTest
Change-Id: Ida773967834e32737b1daac885a2dd71189d32c8
This commit is contained in:
Peter_Liang
2022-02-06 21:45:03 +08:00
parent edb52508d3
commit f71050b515
9 changed files with 291 additions and 7 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -5233,6 +5233,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, Id 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] -->

View File

@@ -57,4 +57,10 @@
android:persistent="false"
android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
<com.android.settingslib.widget.LayoutPreference
android:key="reset"
android:layout="@layout/accessibility_text_reading_reset_button"
android:persistent="false"
android:selectable="false" />
</PreferenceScreen>

View File

@@ -29,10 +29,12 @@ 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 {
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() {
@@ -81,13 +83,17 @@ class PreviewSizeSeekBarController extends BasePreferenceController {
final int dataSize = mSizeData.getValues().size();
final int initialIndex = mSizeData.getInitialIndex();
final LabeledSeekBarPreference seekBarPreference =
screen.findPreference(getPreferenceKey());
mSeekBarPreference = screen.findPreference(getPreferenceKey());
mSeekBarPreference.setMax(dataSize - 1);
mSeekBarPreference.setProgress(initialIndex);
mSeekBarPreference.setContinuousUpdates(true);
mSeekBarPreference.setOnSeekBarChangeListener(mSeekBarChangeListener);
}
seekBarPreference.setMax(dataSize - 1);
seekBarPreference.setProgress(initialIndex);
seekBarPreference.setContinuousUpdates(true);
seekBarPreference.setOnSeekBarChangeListener(mSeekBarChangeListener);
@Override
public void resetState() {
final int defaultProgress = mSizeData.getValues().indexOf(mSizeData.getDefaultValue());
mSeekBarPreference.setProgress(defaultProgress);
}
/**

View File

@@ -16,6 +16,8 @@
package com.android.settings.accessibility;
import static com.android.settings.accessibility.TextReadingResetController.ResetStateListener;
import android.app.settings.SettingsEnums;
import android.content.Context;
@@ -27,6 +29,7 @@ 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
@@ -38,6 +41,7 @@ public class TextReadingPreferenceFragment extends DashboardFragment {
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";
@Override
protected int getPreferenceScreenResId() {
@@ -74,6 +78,13 @@ public class TextReadingPreferenceFragment extends DashboardFragment {
displaySizeController.setInteractionListener(previewController);
controllers.add(displaySizeController);
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;
}

View File

@@ -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();
}
}

View File

@@ -82,4 +82,17 @@ public class PreviewSizeSeekBarControllerTest {
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);
}
}

View File

@@ -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;
}
}
}