Apply the new design of mUserShortcutTypesCache & mUserShortcutTypes in Magnification

Bug: 158540780
Test: atest ToggleScreenMagnificationPreferenceFragmentTest
Change-Id: I941a6e571a5a70f27032b82fcdc00f43b672168f
This commit is contained in:
jasonwshsu
2020-10-30 16:36:10 +08:00
parent 9f54ab9afa
commit ba7b4bb727
2 changed files with 133 additions and 91 deletions

View File

@@ -19,8 +19,6 @@ package com.android.settings.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.accessibility.PreferredShortcuts.retrieveUserShortcutType;
import static com.android.settings.accessibility.PreferredShortcuts.saveUserShortcutType;
import android.app.Dialog; import android.app.Dialog;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
@@ -58,17 +56,13 @@ import java.util.StringJoiner;
*/ */
public class ToggleScreenMagnificationPreferenceFragment extends public class ToggleScreenMagnificationPreferenceFragment extends
ToggleFeaturePreferenceFragment { ToggleFeaturePreferenceFragment {
// TODO(b/147021230): Move duplicated functions with android/internal/accessibility into util.
private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type";
private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener; private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
private CheckBox mSoftwareTypeCheckBox; private CheckBox mSoftwareTypeCheckBox;
private CheckBox mHardwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox;
private CheckBox mTripleTapTypeCheckBox; private CheckBox mTripleTapTypeCheckBox;
// TODO(b/147021230): Will move common functions and variables to
// android/internal/accessibility folder. For now, magnification need to be treated
// individually.
private static final char COMPONENT_NAME_SEPARATOR = ':'; private static final char COMPONENT_NAME_SEPARATOR = ':';
private static final TextUtils.SimpleStringSplitter sStringColonSplitter = private static final TextUtils.SimpleStringSplitter sStringColonSplitter =
new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
@@ -94,12 +88,6 @@ public class ToggleScreenMagnificationPreferenceFragment extends
return super.onCreateView(inflater, container, savedInstanceState); return super.onCreateView(inflater, container, savedInstanceState);
} }
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(EXTRA_SHORTCUT_TYPE, mUserShortcutTypesCache);
super.onSaveInstanceState(outState);
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
@@ -131,21 +119,13 @@ public class ToggleScreenMagnificationPreferenceFragment extends
dialog = AccessibilityEditDialogUtils.showMagnificationEditShortcutDialog( dialog = AccessibilityEditDialogUtils.showMagnificationEditShortcutDialog(
getPrefContext(), dialogTitle, getPrefContext(), dialogTitle,
this::callOnAlertDialogCheckboxClicked); this::callOnAlertDialogCheckboxClicked);
initializeDialogCheckBox(dialog); setupMagnificationEditShortcutDialog(dialog);
return dialog; return dialog;
default: default:
return super.onCreateDialog(dialogId); return super.onCreateDialog(dialogId);
} }
} }
private void setDialogTextAreaClickListener(View dialogView, CheckBox checkBox) {
final View dialogTextArea = dialogView.findViewById(R.id.container);
dialogTextArea.setOnClickListener(v -> {
checkBox.toggle();
updateUserShortcutType(/* saveChanges= */ false);
});
}
@Override @Override
protected void initSettingsPreference() { protected void initSettingsPreference() {
mSettingsPreference = new Preference(getPrefContext()); mSettingsPreference = new Preference(getPrefContext());
@@ -157,8 +137,27 @@ public class ToggleScreenMagnificationPreferenceFragment extends
generalCategory.addPreference(mSettingsPreference); generalCategory.addPreference(mSettingsPreference);
} }
@Override
protected int getShortcutTypeCheckBoxValue() {
if (mSoftwareTypeCheckBox == null || mHardwareTypeCheckBox == null) {
return NOT_SET;
}
int value = UserShortcutType.EMPTY;
if (mSoftwareTypeCheckBox.isChecked()) {
value |= UserShortcutType.SOFTWARE;
}
if (mHardwareTypeCheckBox.isChecked()) {
value |= UserShortcutType.HARDWARE;
}
if (mTripleTapTypeCheckBox.isChecked()) {
value |= UserShortcutType.TRIPLETAP;
}
return value;
}
@VisibleForTesting @VisibleForTesting
void initializeDialogCheckBox(AlertDialog dialog) { void setupMagnificationEditShortcutDialog(AlertDialog dialog) {
final View dialogSoftwareView = dialog.findViewById(R.id.software_shortcut); final View dialogSoftwareView = dialog.findViewById(R.id.software_shortcut);
mSoftwareTypeCheckBox = dialogSoftwareView.findViewById(R.id.checkbox); mSoftwareTypeCheckBox = dialogSoftwareView.findViewById(R.id.checkbox);
setDialogTextAreaClickListener(dialogSoftwareView, mSoftwareTypeCheckBox); setDialogTextAreaClickListener(dialogSoftwareView, mSoftwareTypeCheckBox);
@@ -172,49 +171,46 @@ public class ToggleScreenMagnificationPreferenceFragment extends
setDialogTextAreaClickListener(dialogTripleTapView, mTripleTapTypeCheckBox); setDialogTextAreaClickListener(dialogTripleTapView, mTripleTapTypeCheckBox);
final View advancedView = dialog.findViewById(R.id.advanced_shortcut); final View advancedView = dialog.findViewById(R.id.advanced_shortcut);
updateAlertDialogCheckState();
// Shows the triple tap checkbox directly if clicked.
if (mTripleTapTypeCheckBox.isChecked()) { if (mTripleTapTypeCheckBox.isChecked()) {
advancedView.setVisibility(View.GONE); advancedView.setVisibility(View.GONE);
dialogTripleTapView.setVisibility(View.VISIBLE); dialogTripleTapView.setVisibility(View.VISIBLE);
} }
updateMagnificationEditShortcutDialogCheckBox();
} }
private void updateAlertDialogCheckState() { private void setDialogTextAreaClickListener(View dialogView, CheckBox checkBox) {
if (mUserShortcutTypesCache != UserShortcutType.EMPTY) { final View dialogTextArea = dialogView.findViewById(R.id.container);
updateCheckStatus(mSoftwareTypeCheckBox, UserShortcutType.SOFTWARE); dialogTextArea.setOnClickListener(v -> checkBox.toggle());
updateCheckStatus(mHardwareTypeCheckBox, UserShortcutType.HARDWARE);
updateCheckStatus(mTripleTapTypeCheckBox, UserShortcutType.TRIPLETAP);
}
} }
private void updateCheckStatus(CheckBox checkBox, @UserShortcutType int type) { private void updateMagnificationEditShortcutDialogCheckBox() {
checkBox.setChecked((mUserShortcutTypesCache & type) == type); // If it is during onConfigChanged process then restore the value, or get the saved value
// when shortcutPreference is checked.
int value = restoreOnConfigChangedValue();
if (value == NOT_SET) {
final int lastNonEmptyUserShortcutType = PreferredShortcuts.retrieveUserShortcutType(
getPrefContext(), MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
value = mShortcutPreference.isChecked() ? lastNonEmptyUserShortcutType
: UserShortcutType.EMPTY;
}
mSoftwareTypeCheckBox.setChecked(
hasShortcutType(value, UserShortcutType.SOFTWARE));
mHardwareTypeCheckBox.setChecked(
hasShortcutType(value, UserShortcutType.HARDWARE));
mTripleTapTypeCheckBox.setChecked(
hasShortcutType(value, UserShortcutType.TRIPLETAP));
} }
@VisibleForTesting private int restoreOnConfigChangedValue() {
void updateUserShortcutType(boolean saveChanges) { final int savedValue = mSavedCheckBoxValue;
mUserShortcutTypesCache = UserShortcutType.EMPTY; mSavedCheckBoxValue = NOT_SET;
if (mSoftwareTypeCheckBox.isChecked()) { return savedValue;
mUserShortcutTypesCache |= UserShortcutType.SOFTWARE; }
}
if (mHardwareTypeCheckBox.isChecked()) {
mUserShortcutTypesCache |= UserShortcutType.HARDWARE;
}
if (mTripleTapTypeCheckBox.isChecked()) {
mUserShortcutTypesCache |= UserShortcutType.TRIPLETAP;
}
if (saveChanges) { private boolean hasShortcutType(int value, @UserShortcutType int type) {
final boolean isChanged = (mUserShortcutTypesCache != UserShortcutType.EMPTY); return (value & type) == type;
if (isChanged) {
final PreferredShortcut shortcut = new PreferredShortcut(
MAGNIFICATION_CONTROLLER_NAME, mUserShortcutTypesCache);
saveUserShortcutType(getPrefContext(), shortcut);
}
mUserShortcutTypes = mUserShortcutTypesCache;
}
} }
@Override @Override
@@ -223,8 +219,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
return context.getText(R.string.switch_off_text); return context.getText(R.string.switch_off_text);
} }
final int shortcutType = retrieveUserShortcutType(context, MAGNIFICATION_CONTROLLER_NAME, final int shortcutType = PreferredShortcuts.retrieveUserShortcutType(context,
UserShortcutType.EMPTY); MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
int resId = R.string.accessibility_shortcut_edit_summary_software; int resId = R.string.accessibility_shortcut_edit_summary_software;
if (AccessibilityUtil.isGestureNavigateEnabled(context)) { if (AccessibilityUtil.isGestureNavigateEnabled(context)) {
resId = AccessibilityUtil.isTouchExploreEnabled(context) resId = AccessibilityUtil.isTouchExploreEnabled(context)
@@ -261,10 +257,12 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
updateUserShortcutType(/* saveChanges= */ true); final int value = getShortcutTypeCheckBoxValue();
optInAllMagnificationValuesToSettings(getPrefContext(), mUserShortcutTypes);
optOutAllMagnificationValuesFromSettings(getPrefContext(), ~mUserShortcutTypes); saveNonEmptyUserShortcutType(value);
mShortcutPreference.setChecked(mUserShortcutTypes != UserShortcutType.EMPTY); optInAllMagnificationValuesToSettings(getPrefContext(), value);
optOutAllMagnificationValuesFromSettings(getPrefContext(), ~value);
mShortcutPreference.setChecked(value != UserShortcutType.EMPTY);
mShortcutPreference.setSummary( mShortcutPreference.setSummary(
getShortcutTypeSummary(getPrefContext())); getShortcutTypeSummary(getPrefContext()));
} }
@@ -312,7 +310,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
public void onToggleClicked(ShortcutPreference preference) { public void onToggleClicked(ShortcutPreference preference) {
final int shortcutTypes = retrieveUserShortcutType(getPrefContext(), final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(),
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE); MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
if (preference.isChecked()) { if (preference.isChecked()) {
optInAllMagnificationValuesToSettings(getPrefContext(), shortcutTypes); optInAllMagnificationValuesToSettings(getPrefContext(), shortcutTypes);
@@ -325,26 +323,16 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
public void onSettingsClicked(ShortcutPreference preference) { public void onSettingsClicked(ShortcutPreference preference) {
// Do not restore shortcut in shortcut chooser dialog when shortcutPreference is turned off.
mUserShortcutTypesCache = mShortcutPreference.isChecked()
? retrieveUserShortcutType(getPrefContext(),
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE)
: UserShortcutType.EMPTY;
showDialog(DialogEnums.MAGNIFICATION_EDIT_SHORTCUT); showDialog(DialogEnums.MAGNIFICATION_EDIT_SHORTCUT);
} }
@Override @Override
protected void updateShortcutPreferenceData() { protected void updateShortcutPreferenceData() {
// Get the user shortcut type from settings provider. final int shortcutTypes = getUserShortcutTypeFromSettings(getPrefContext());
mUserShortcutTypes = getUserShortcutTypeFromSettings(getPrefContext()); if (shortcutTypes != UserShortcutType.EMPTY) {
if (mUserShortcutTypes != UserShortcutType.EMPTY) {
final PreferredShortcut shortcut = new PreferredShortcut( final PreferredShortcut shortcut = new PreferredShortcut(
MAGNIFICATION_CONTROLLER_NAME, mUserShortcutTypes); MAGNIFICATION_CONTROLLER_NAME, shortcutTypes);
saveUserShortcutType(getPrefContext(), shortcut); PreferredShortcuts.saveUserShortcutType(getPrefContext(), shortcut);
} else {
// Get the user shortcut type from shared_prefs if cannot get from settings provider.
mUserShortcutTypes = retrieveUserShortcutType(getPrefContext(),
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
} }
} }
@@ -365,13 +353,24 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
protected void updateShortcutPreference() { protected void updateShortcutPreference() {
final int shortcutTypes = retrieveUserShortcutType(getPrefContext(), final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(),
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE); MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
mShortcutPreference.setChecked( mShortcutPreference.setChecked(
hasMagnificationValuesInSettings(getPrefContext(), shortcutTypes)); hasMagnificationValuesInSettings(getPrefContext(), shortcutTypes));
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
} }
@VisibleForTesting
void saveNonEmptyUserShortcutType(int type) {
if (type == UserShortcutType.EMPTY) {
return;
}
final PreferredShortcut shortcut = new PreferredShortcut(
MAGNIFICATION_CONTROLLER_NAME, type);
PreferredShortcuts.saveUserShortcutType(getPrefContext(), shortcut);
}
@VisibleForTesting @VisibleForTesting
static void optInAllMagnificationValuesToSettings(Context context, int shortcutTypes) { static void optInAllMagnificationValuesToSettings(Context context, int shortcutTypes) {
if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) {

View File

@@ -19,7 +19,7 @@ package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType; import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.EXTRA_SHORTCUT_TYPE; import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.KEY_SAVED_USER_SHORTCUT_TYPE;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
@@ -62,6 +62,7 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
PLACEHOLDER_PACKAGE_NAME + ".mock_a11y_service"; PLACEHOLDER_PACKAGE_NAME + ".mock_a11y_service";
private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName( private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME); PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
private static final String PLACEHOLDER_DIALOG_TITLE = "title";
private static final String SOFTWARE_SHORTCUT_KEY = private static final String SOFTWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS; Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
@@ -162,8 +163,10 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
public void updateShortcutPreferenceData_assignDefaultValueToVariable() { public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
mFragment.updateShortcutPreferenceData(); mFragment.updateShortcutPreferenceData();
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
// Compare to default UserShortcutType // Compare to default UserShortcutType
assertThat(mFragment.mUserShortcutTypes).isEqualTo(UserShortcutType.SOFTWARE); assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE);
} }
@Test @Test
@@ -172,8 +175,9 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
setMagnificationTripleTapEnabled(/* enabled= */ true); setMagnificationTripleTapEnabled(/* enabled= */ true);
mFragment.updateShortcutPreferenceData(); mFragment.updateShortcutPreferenceData();
assertThat(mFragment.mUserShortcutTypes).isEqualTo( final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
UserShortcutType.SOFTWARE | UserShortcutType.TRIPLETAP); MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.TRIPLETAP);
} }
@Test @Test
@@ -184,27 +188,66 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
putUserShortcutTypeIntoSharedPreference(mContext, tripleTapShortcut); putUserShortcutTypeIntoSharedPreference(mContext, tripleTapShortcut);
mFragment.updateShortcutPreferenceData(); mFragment.updateShortcutPreferenceData();
assertThat(mFragment.mUserShortcutTypes).isEqualTo(UserShortcutType.TRIPLETAP); final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
assertThat(expectedType).isEqualTo(UserShortcutType.TRIPLETAP);
}
@Test
public void setupMagnificationEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue() {
mContext.setTheme(R.style.Theme_AppCompat);
final AlertDialog dialog = AccessibilityEditDialogUtils.showMagnificationEditShortcutDialog(
mContext, PLACEHOLDER_DIALOG_TITLE, this::callEmptyOnClicked);
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
null);
mFragment.mShortcutPreference = shortcutPreference;
mFragment.mShortcutPreference.setChecked(false);
mFragment.setupMagnificationEditShortcutDialog(dialog);
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
assertThat(checkboxValue).isEqualTo(UserShortcutType.EMPTY);
}
@Test
public void setupMagnificationEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue() {
mContext.setTheme(R.style.Theme_AppCompat);
final AlertDialog dialog = AccessibilityEditDialogUtils.showMagnificationEditShortcutDialog(
mContext, PLACEHOLDER_DIALOG_TITLE, this::callEmptyOnClicked);
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
null);
final PreferredShortcut tripletapShortcut = new PreferredShortcut(
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.TRIPLETAP);
mFragment.mShortcutPreference = shortcutPreference;
PreferredShortcuts.saveUserShortcutType(mContext, tripletapShortcut);
mFragment.mShortcutPreference.setChecked(true);
mFragment.setupMagnificationEditShortcutDialog(dialog);
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
assertThat(checkboxValue).isEqualTo(UserShortcutType.TRIPLETAP);
} }
@Test @Test
@Config(shadows = ShadowFragment.class) @Config(shadows = ShadowFragment.class)
public void restoreValueFromSavedInstanceState_assignToVariable() { public void restoreValueFromSavedInstanceState_assignToVariable() {
mContext.setTheme(R.style.Theme_AppCompat); mContext.setTheme(R.style.Theme_AppCompat);
final String dialogTitle = "title";
final AlertDialog dialog = AccessibilityEditDialogUtils.showMagnificationEditShortcutDialog( final AlertDialog dialog = AccessibilityEditDialogUtils.showMagnificationEditShortcutDialog(
mContext, dialogTitle, this::callEmptyOnClicked); mContext, PLACEHOLDER_DIALOG_TITLE, this::callEmptyOnClicked);
final Bundle savedInstanceState = new Bundle(); final Bundle savedInstanceState = new Bundle();
mFragment.mShortcutPreference = new ShortcutPreference(mContext, /* attrs= */ null);
savedInstanceState.putInt(EXTRA_SHORTCUT_TYPE, savedInstanceState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE,
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE); UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP);
mFragment.onCreate(savedInstanceState); mFragment.onCreate(savedInstanceState);
mFragment.initializeDialogCheckBox(dialog); mFragment.setupMagnificationEditShortcutDialog(dialog);
mFragment.updateUserShortcutType(true); final int value = mFragment.getShortcutTypeCheckBoxValue();
mFragment.saveNonEmptyUserShortcutType(value);
assertThat(mFragment.mUserShortcutTypes).isEqualTo(
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
assertThat(value).isEqualTo(6);
assertThat(expectedType).isEqualTo(UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP);
} }
private void putStringIntoSettings(String key, String componentName) { private void putStringIntoSettings(String key, String componentName) {