Modify flow in ToggleFeaturePreferenceFragment

* Show edit shortcut dialog should belong to the basic feature, so move
them back to ToggleFeaturePreferenceFragment
* Add test cases for UserShortcutType to prepare to further refactor

Bug: 158540780
Test: atest ToggleFeaturePreferenceFragmentTest
Change-Id: Ia84bea5581f85d199f395b2065652ce69738abbf
This commit is contained in:
jasonwshsu
2020-07-13 03:59:36 +08:00
committed by Jason Hsu
parent 1044467d33
commit 1a1ae82460
8 changed files with 339 additions and 72 deletions

View File

@@ -97,12 +97,6 @@ public class LaunchAccessibilityActivityPreferenceFragment extends
mSettingsTitle = (mSettingsIntent == null) ? null : settingsTitle; mSettingsTitle = (mSettingsIntent == null) ? null : settingsTitle;
} }
@Override
public void onSettingsClicked(ShortcutPreference preference) {
super.onSettingsClicked(preference);
showDialog(DialogEnums.EDIT_SHORTCUT);
}
@Override @Override
int getUserShortcutTypes() { int getUserShortcutTypes() {
return AccessibilityUtil.getUserShortcutTypesFromSettings(getPrefContext(), return AccessibilityUtil.getUserShortcutTypesFromSettings(getPrefContext(),

View File

@@ -311,7 +311,11 @@ public class ToggleAccessibilityServicePreferenceFragment extends
@Override @Override
public void onSettingsClicked(ShortcutPreference preference) { public void onSettingsClicked(ShortcutPreference preference) {
super.onSettingsClicked(preference); // Do not restore shortcut in shortcut chooser dialog when shortcutPreference is turned off.
mUserShortcutTypesCache = mShortcutPreference.isChecked()
? getUserShortcutTypes(getPrefContext(), UserShortcutType.SOFTWARE)
: UserShortcutType.EMPTY;
final boolean isServiceOnOrShortcutAdded = mShortcutPreference.isChecked() final boolean isServiceOnOrShortcutAdded = mShortcutPreference.isChecked()
|| mToggleServiceDividerSwitchPreference.isChecked(); || mToggleServiceDividerSwitchPreference.isChecked();
showPopupDialog(isServiceOnOrShortcutAdded ? DialogEnums.EDIT_SHORTCUT showPopupDialog(isServiceOnOrShortcutAdded ? DialogEnums.EDIT_SHORTCUT

View File

@@ -122,12 +122,6 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere
return R.string.help_url_color_inversion; return R.string.help_url_color_inversion;
} }
@Override
public void onSettingsClicked(ShortcutPreference preference) {
super.onSettingsClicked(preference);
showDialog(DialogEnums.EDIT_SHORTCUT);
}
@Override @Override
int getUserShortcutTypes() { int getUserShortcutTypes() {
return AccessibilityUtil.getUserShortcutTypesFromSettings(getPrefContext(), return AccessibilityUtil.getUserShortcutTypesFromSettings(getPrefContext(),

View File

@@ -194,12 +194,6 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe
}); });
} }
@Override
public void onSettingsClicked(ShortcutPreference preference) {
super.onSettingsClicked(preference);
showDialog(DialogEnums.EDIT_SHORTCUT);
}
@Override @Override
int getUserShortcutTypes() { int getUserShortcutTypes() {
return AccessibilityUtil.getUserShortcutTypesFromSettings(getPrefContext(), return AccessibilityUtil.getUserShortcutTypesFromSettings(getPrefContext(),

View File

@@ -57,6 +57,8 @@ import com.android.settings.widget.SwitchBar;
import com.android.settingslib.accessibility.AccessibilityUtils; import com.android.settingslib.accessibility.AccessibilityUtils;
import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.FooterPreference;
import com.google.common.annotations.VisibleForTesting;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
@@ -87,19 +89,24 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
protected Uri mImageUri; protected Uri mImageUri;
private CharSequence mDescription; private CharSequence mDescription;
protected CharSequence mHtmlDescription; protected CharSequence mHtmlDescription;
// Used to restore the edit dialog status.
protected int mUserShortcutTypesCache = UserShortcutType.EMPTY;
private static final String DRAWABLE_FOLDER = "drawable"; private static final String DRAWABLE_FOLDER = "drawable";
protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service"; protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service";
protected static final String KEY_GENERAL_CATEGORY = "general_categories"; protected static final String KEY_GENERAL_CATEGORY = "general_categories";
protected static final String KEY_INTRODUCTION_CATEGORY = "introduction_categories"; protected static final String KEY_INTRODUCTION_CATEGORY = "introduction_categories";
private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference"; private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type"; @VisibleForTesting
static final String EXTRA_SHORTCUT_TYPE = "shortcut_type";
private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener; private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
private int mUserShortcutTypes = UserShortcutType.EMPTY; private SettingsContentObserver mSettingsContentObserver;
private CheckBox mSoftwareTypeCheckBox; private CheckBox mSoftwareTypeCheckBox;
private CheckBox mHardwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox;
private SettingsContentObserver mSettingsContentObserver;
// Used to restore the edit dialog status.
protected int mUserShortcutTypesCache = UserShortcutType.EMPTY;
protected int mUserShortcutTypes = UserShortcutType.EMPTY;
// For html description of accessibility service, must follow the rule, such as // For html description of accessibility service, must follow the rule, such as
// <img src="R.drawable.fileName"/>, a11y settings will get the resources successfully. // <img src="R.drawable.fileName"/>, a11y settings will get the resources successfully.
@@ -121,6 +128,12 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// Restore the user shortcut type.
if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_SHORTCUT_TYPE)) {
mUserShortcutTypesCache = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE,
UserShortcutType.EMPTY);
}
setupDefaultShortcutIfNecessary(getPrefContext()); setupDefaultShortcutIfNecessary(getPrefContext());
final int resId = getPreferenceScreenResId(); final int resId = getPreferenceScreenResId();
if (resId <= 0) { if (resId <= 0) {
@@ -150,7 +163,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
initAnimatedImagePreference(); initAnimatedImagePreference();
initToggleServiceDividerSwitchPreference(); initToggleServiceDividerSwitchPreference();
initGeneralCategory(); initGeneralCategory();
initShortcutPreference(savedInstanceState); initShortcutPreference();
initSettingsPreference(); initSettingsPreference();
initHtmlTextPreference(); initHtmlTextPreference();
initFooterPreference(); initFooterPreference();
@@ -521,7 +534,8 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
}); });
} }
private void initializeDialogCheckBox(Dialog dialog) { @VisibleForTesting
void initializeDialogCheckBox(Dialog 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);
@@ -544,7 +558,8 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
checkBox.setChecked((mUserShortcutTypesCache & type) == type); checkBox.setChecked((mUserShortcutTypesCache & type) == type);
} }
private void updateUserShortcutType(boolean saveChanges) { @VisibleForTesting
void updateUserShortcutType(boolean saveChanges) {
mUserShortcutTypesCache = UserShortcutType.EMPTY; mUserShortcutTypesCache = UserShortcutType.EMPTY;
if (mSoftwareTypeCheckBox.isChecked()) { if (mSoftwareTypeCheckBox.isChecked()) {
mUserShortcutTypesCache |= UserShortcutType.SOFTWARE; mUserShortcutTypesCache |= UserShortcutType.SOFTWARE;
@@ -677,13 +692,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
} }
} }
protected void initShortcutPreference(Bundle savedInstanceState) { protected void initShortcutPreference() {
// Restore the user shortcut type.
if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_SHORTCUT_TYPE)) {
mUserShortcutTypesCache = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE,
UserShortcutType.EMPTY);
}
// Initial the shortcut preference. // Initial the shortcut preference.
mShortcutPreference = new ShortcutPreference(getPrefContext(), null); mShortcutPreference = new ShortcutPreference(getPrefContext(), null);
mShortcutPreference.setPersistent(false); mShortcutPreference.setPersistent(false);
@@ -737,6 +746,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
mUserShortcutTypesCache = mShortcutPreference.isChecked() mUserShortcutTypesCache = mShortcutPreference.isChecked()
? getUserShortcutTypes(getPrefContext(), UserShortcutType.SOFTWARE) ? getUserShortcutTypes(getPrefContext(), UserShortcutType.SOFTWARE)
: UserShortcutType.EMPTY; : UserShortcutType.EMPTY;
showDialog(DialogEnums.EDIT_SHORTCUT);
} }
private void createFooterPreference(CharSequence title) { private void createFooterPreference(CharSequence title) {

View File

@@ -62,7 +62,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type"; private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type";
private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener; private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
private int mUserShortcutType = UserShortcutType.EMPTY;
private CheckBox mSoftwareTypeCheckBox; private CheckBox mSoftwareTypeCheckBox;
private CheckBox mHardwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox;
private CheckBox mTripleTapTypeCheckBox; private CheckBox mTripleTapTypeCheckBox;
@@ -158,7 +158,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
generalCategory.addPreference(mSettingsPreference); generalCategory.addPreference(mSettingsPreference);
} }
private void initializeDialogCheckBox(AlertDialog dialog) { @VisibleForTesting
void initializeDialogCheckBox(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);
@@ -193,7 +194,8 @@ public class ToggleScreenMagnificationPreferenceFragment extends
checkBox.setChecked((mUserShortcutTypesCache & type) == type); checkBox.setChecked((mUserShortcutTypesCache & type) == type);
} }
private void updateUserShortcutType(boolean saveChanges) { @VisibleForTesting
void updateUserShortcutType(boolean saveChanges) {
mUserShortcutTypesCache = UserShortcutType.EMPTY; mUserShortcutTypesCache = UserShortcutType.EMPTY;
if (mSoftwareTypeCheckBox.isChecked()) { if (mSoftwareTypeCheckBox.isChecked()) {
mUserShortcutTypesCache |= UserShortcutType.SOFTWARE; mUserShortcutTypesCache |= UserShortcutType.SOFTWARE;
@@ -210,7 +212,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
if (isChanged) { if (isChanged) {
setUserShortcutType(getPrefContext(), mUserShortcutTypesCache); setUserShortcutType(getPrefContext(), mUserShortcutTypesCache);
} }
mUserShortcutType = mUserShortcutTypesCache; mUserShortcutTypes = mUserShortcutTypesCache;
} }
} }
@@ -289,9 +291,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
updateUserShortcutType(/* saveChanges= */ true); updateUserShortcutType(/* saveChanges= */ true);
optInAllMagnificationValuesToSettings(getPrefContext(), mUserShortcutType); optInAllMagnificationValuesToSettings(getPrefContext(), mUserShortcutTypes);
optOutAllMagnificationValuesFromSettings(getPrefContext(), ~mUserShortcutType); optOutAllMagnificationValuesFromSettings(getPrefContext(), ~mUserShortcutTypes);
mShortcutPreference.setChecked(mUserShortcutType != UserShortcutType.EMPTY); mShortcutPreference.setChecked(mUserShortcutTypes != UserShortcutType.EMPTY);
mShortcutPreference.setSummary( mShortcutPreference.setSummary(
getShortcutTypeSummary(getPrefContext())); getShortcutTypeSummary(getPrefContext()));
} }
@@ -361,17 +363,17 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override @Override
protected void updateShortcutPreferenceData() { protected void updateShortcutPreferenceData() {
// Get the user shortcut type from settings provider. // Get the user shortcut type from settings provider.
mUserShortcutType = getUserShortcutTypeFromSettings(getPrefContext()); mUserShortcutTypes = getUserShortcutTypeFromSettings(getPrefContext());
if (mUserShortcutType != UserShortcutType.EMPTY) { if (mUserShortcutTypes != UserShortcutType.EMPTY) {
setUserShortcutType(getPrefContext(), mUserShortcutType); setUserShortcutType(getPrefContext(), mUserShortcutTypes);
} else { } else {
// Get the user shortcut type from shared_prefs if cannot get from settings provider. // Get the user shortcut type from shared_prefs if cannot get from settings provider.
mUserShortcutType = getUserShortcutTypes(getPrefContext(), UserShortcutType.SOFTWARE); mUserShortcutTypes = getUserShortcutTypes(getPrefContext(), UserShortcutType.SOFTWARE);
} }
} }
@Override @Override
protected void initShortcutPreference(Bundle savedInstanceState) { protected void initShortcutPreference() {
mShortcutPreference = new ShortcutPreference(getPrefContext(), null); mShortcutPreference = new ShortcutPreference(getPrefContext(), null);
mShortcutPreference.setPersistent(false); mShortcutPreference.setPersistent(false);
mShortcutPreference.setKey(getShortcutPreferenceKey()); mShortcutPreference.setKey(getShortcutPreferenceKey());

View File

@@ -16,44 +16,87 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.EXTRA_SHORTCUT_TYPE;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.XmlRes; import androidx.annotation.XmlRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.preference.PreferenceManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import com.android.settings.accessibility.ToggleFeaturePreferenceFragment.AccessibilityUserShortcutType; import com.android.settings.accessibility.ToggleFeaturePreferenceFragment.AccessibilityUserShortcutType;
import com.android.settings.testutils.shadow.ShadowFragment;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.androidx.fragment.FragmentController; import org.robolectric.shadows.androidx.fragment.FragmentController;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** Tests for {@link ToggleFeaturePreferenceFragment} */
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class ToggleFeaturePreferenceFragmentTest { public class ToggleFeaturePreferenceFragmentTest {
private ToggleFeaturePreferenceFragmentTestable mFragment;
private static final String TEST_SERVICE_KEY_1 = "abc:111"; private static final String TEST_SERVICE_KEY_1 = "abc:111";
private static final String TEST_SERVICE_KEY_2 = "mno:222"; private static final String TEST_SERVICE_KEY_2 = "mno:222";
private static final String TEST_SERVICE_KEY_3 = "xyz:333"; private static final String TEST_SERVICE_KEY_3 = "xyz:333";
private static final String TEST_SERVICE_NAME_1 = "abc"; private static final String TEST_SERVICE_NAME_1 = "abc";
private static final int TEST_SERVICE_VALUE_1 = 111; private static final int TEST_SERVICE_VALUE_1 = 111;
private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
private static final String PLACEHOLDER_CLASS_NAME = PLACEHOLDER_PACKAGE_NAME + ".placeholder";
private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
private static final String SOFTWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
private static final String HARDWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
private TestToggleFeaturePreferenceFragment mFragment;
private Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private PreferenceManager mPreferenceManager;
@Before
public void setUpTestFragment() {
MockitoAnnotations.initMocks(this);
mFragment = spy(new TestToggleFeaturePreferenceFragment());
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
when(mFragment.getContext()).thenReturn(mContext);
doReturn(null).when(mFragment).getPreferenceScreen();
}
@Test @Test
public void a11yUserShortcutType_setConcatString_shouldReturnTargetValue() { public void a11yUserShortcutType_setConcatString_shouldReturnTargetValue() {
final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType( final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType(
@@ -109,7 +152,6 @@ public class ToggleFeaturePreferenceFragmentTest {
@Test @Test
public void createFragment_shouldOnlyAddPreferencesOnce() { public void createFragment_shouldOnlyAddPreferencesOnce() {
mFragment = spy(new ToggleFeaturePreferenceFragmentTestable());
FragmentController.setupFragment(mFragment, FragmentActivity.class, FragmentController.setupFragment(mFragment, FragmentActivity.class,
/* containerViewId= */ 0, /* bundle= */null); /* containerViewId= */ 0, /* bundle= */null);
@@ -117,7 +159,75 @@ public class ToggleFeaturePreferenceFragmentTest {
verify(mFragment).addPreferencesFromResource(R.xml.placeholder_prefs); verify(mFragment).addPreferencesFromResource(R.xml.placeholder_prefs);
} }
public static class ToggleFeaturePreferenceFragmentTestable @Test
public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
mFragment.updateShortcutPreferenceData();
// Compare to default UserShortcutType
assertThat(mFragment.mUserShortcutTypes).isEqualTo(UserShortcutType.SOFTWARE);
}
@Test
public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
mFragment.updateShortcutPreferenceData();
assertThat(mFragment.mUserShortcutTypes).isEqualTo(
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
}
@Test
public void updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable() {
mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
final AccessibilityUserShortcutType hardwareShortcut = new AccessibilityUserShortcutType(
PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
putUserShortcutTypeIntoSharedPreference(mContext, hardwareShortcut);
mFragment.updateShortcutPreferenceData();
assertThat(mFragment.mUserShortcutTypes).isEqualTo(UserShortcutType.HARDWARE);
}
@Test
@Config(shadows = ShadowFragment.class)
public void restoreValueFromSavedInstanceState_assignToVariable() {
mContext.setTheme(R.style.Theme_AppCompat);
final String dialogTitle = "title";
final AlertDialog dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(
mContext, dialogTitle, this::callEmptyOnClicked);
final Bundle savedInstanceState = new Bundle();
mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
savedInstanceState.putInt(EXTRA_SHORTCUT_TYPE,
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
mFragment.onCreate(savedInstanceState);
mFragment.initializeDialogCheckBox(dialog);
mFragment.updateUserShortcutType(true);
assertThat(mFragment.mUserShortcutTypes).isEqualTo(
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
}
private void putStringIntoSettings(String key, String componentName) {
Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
}
private void putUserShortcutTypeIntoSharedPreference(Context context,
AccessibilityUserShortcutType shortcut) {
Set<String> value = new HashSet<>(Collections.singletonList(shortcut.flattenToString()));
SharedPreferenceUtils.setUserShortcutType(context, value);
}
private void callEmptyOnClicked(DialogInterface dialog, int which) {}
public static class TestToggleFeaturePreferenceFragment
extends ToggleFeaturePreferenceFragment { extends ToggleFeaturePreferenceFragment {
@Override @Override
@@ -145,14 +255,25 @@ public class ToggleFeaturePreferenceFragmentTest {
return mock(View.class); return mock(View.class);
} }
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// do nothing
}
@Override
public void onDestroyView() {
// do nothing
}
@Override @Override
public void addPreferencesFromResource(@XmlRes int preferencesResId) { public void addPreferencesFromResource(@XmlRes int preferencesResId) {
// do nothing // do nothing
} }
@Override @Override
public void onViewCreated(View view, Bundle savedInstanceState) { protected void updateShortcutPreference() {
// do nothing // UI related function, do nothing in tests
} }
} }
} }

View File

@@ -19,40 +19,83 @@ 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.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.XmlRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.PreferenceManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.accessibility.ToggleFeaturePreferenceFragment.AccessibilityUserShortcutType;
import com.android.settings.testutils.shadow.ShadowFragment;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class ToggleScreenMagnificationPreferenceFragmentTest { public class ToggleScreenMagnificationPreferenceFragmentTest {
private static final String DUMMY_PACKAGE_NAME = "com.mock.example"; private static final String PLACEHOLDER_PACKAGE_NAME = "com.mock.example";
private static final String DUMMY_CLASS_NAME = DUMMY_PACKAGE_NAME + ".mock_a11y_service"; private static final String PLACEHOLDER_CLASS_NAME =
private static final ComponentName DUMMY_COMPONENT_NAME = new ComponentName(DUMMY_PACKAGE_NAME, PLACEHOLDER_PACKAGE_NAME + ".mock_a11y_service";
DUMMY_CLASS_NAME); private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
private static final String SOFTWARE_SHORTCUT_KEY = private static final String SOFTWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS; Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
private static final String HARDWARE_SHORTCUT_KEY = private static final String HARDWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
private static final String TRIPLETAP_SHORTCUT_KEY = private static final String TRIPLETAP_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED; Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
private static final String MAGNIFICATION_CONTROLLER_NAME = private static final String MAGNIFICATION_CONTROLLER_NAME =
"com.android.server.accessibility.MagnificationController"; "com.android.server.accessibility.MagnificationController";
private Context mContext; private TestToggleScreenMagnificationPreferenceFragment mFragment;
private Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private PreferenceManager mPreferenceManager;
@Mock
private FragmentActivity mActivity;
@Before @Before
public void setUp() { public void setUpTestFragment() {
mContext = RuntimeEnvironment.application; MockitoAnnotations.initMocks(this);
mFragment = spy(new TestToggleScreenMagnificationPreferenceFragment());
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
when(mFragment.getContext()).thenReturn(mContext);
doReturn(null).when(mFragment).getPreferenceScreen();
doReturn(mActivity).when(mFragment).getActivity();
} }
@Test @Test
@@ -78,14 +121,13 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
public void optInAllValuesToSettings_existOtherValue_optInValue_haveMatchString() { public void optInAllValuesToSettings_existOtherValue_optInValue_haveMatchString() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(mContext, ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(mContext,
UserShortcutType.SOFTWARE); UserShortcutType.SOFTWARE);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
DUMMY_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME); PLACEHOLDER_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME);
} }
@Test @Test
@@ -107,27 +149,83 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
@Test @Test
public void optOutValueFromSettings_existOtherValue_optOutValue_haveMatchString() { public void optOutValueFromSettings_existOtherValue_optOutValue_haveMatchString() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, putStringIntoSettings(SOFTWARE_SHORTCUT_KEY,
DUMMY_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME); PLACEHOLDER_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME);
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, putStringIntoSettings(HARDWARE_SHORTCUT_KEY,
DUMMY_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME); PLACEHOLDER_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME);
int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE; int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE;
ToggleScreenMagnificationPreferenceFragment.optOutAllMagnificationValuesFromSettings( ToggleScreenMagnificationPreferenceFragment.optOutAllMagnificationValuesFromSettings(
mContext, shortcutTypes); mContext, shortcutTypes);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
DUMMY_COMPONENT_NAME.flattenToString()); PLACEHOLDER_COMPONENT_NAME.flattenToString());
assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEqualTo( assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEqualTo(
DUMMY_COMPONENT_NAME.flattenToString()); PLACEHOLDER_COMPONENT_NAME.flattenToString());
}
@Test
public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
mFragment.updateShortcutPreferenceData();
// Compare to default UserShortcutType
assertThat(mFragment.mUserShortcutTypes).isEqualTo(UserShortcutType.SOFTWARE);
}
@Test
public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME);
setMagnificationTripleTapEnabled(/* enabled= */ true);
mFragment.updateShortcutPreferenceData();
assertThat(mFragment.mUserShortcutTypes).isEqualTo(
UserShortcutType.SOFTWARE | UserShortcutType.TRIPLETAP);
}
@Test
public void updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable() {
final AccessibilityUserShortcutType tripleTapShortcut = new AccessibilityUserShortcutType(
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.TRIPLETAP);
putUserShortcutTypeIntoSharedPreference(mContext, tripleTapShortcut);
mFragment.updateShortcutPreferenceData();
assertThat(mFragment.mUserShortcutTypes).isEqualTo(UserShortcutType.TRIPLETAP);
}
@Test
@Config(shadows = ShadowFragment.class)
public void restoreValueFromSavedInstanceState_assignToVariable() {
mContext.setTheme(R.style.Theme_AppCompat);
final String dialogTitle = "title";
final AlertDialog dialog = AccessibilityEditDialogUtils.showMagnificationEditShortcutDialog(
mContext, dialogTitle, this::callEmptyOnClicked);
final Bundle savedInstanceState = new Bundle();
savedInstanceState.putInt(EXTRA_SHORTCUT_TYPE,
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
mFragment.onCreate(savedInstanceState);
mFragment.initializeDialogCheckBox(dialog);
mFragment.updateUserShortcutType(true);
assertThat(mFragment.mUserShortcutTypes).isEqualTo(
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
} }
private void putStringIntoSettings(String key, String componentName) { private void putStringIntoSettings(String key, String componentName) {
Settings.Secure.putString(mContext.getContentResolver(), key, componentName); Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
} }
private void putUserShortcutTypeIntoSharedPreference(Context context,
AccessibilityUserShortcutType shortcut) {
Set<String> value = new HashSet<>(Collections.singletonList(shortcut.flattenToString()));
SharedPreferenceUtils.setUserShortcutType(context, value);
}
private void setMagnificationTripleTapEnabled(boolean enabled) { private void setMagnificationTripleTapEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.putInt(mContext.getContentResolver(), TRIPLETAP_SHORTCUT_KEY,
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, enabled ? ON : OFF); enabled ? ON : OFF);
} }
private String getStringFromSettings(String key) { private String getStringFromSettings(String key) {
@@ -135,7 +233,57 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
} }
private boolean getMagnificationTripleTapStatus() { private boolean getMagnificationTripleTapStatus() {
return Settings.Secure.getInt(mContext.getContentResolver(), return Settings.Secure.getInt(mContext.getContentResolver(), TRIPLETAP_SHORTCUT_KEY, OFF)
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON; == ON;
}
private void callEmptyOnClicked(DialogInterface dialog, int which) {}
public static class TestToggleScreenMagnificationPreferenceFragment
extends ToggleScreenMagnificationPreferenceFragment {
@Override
protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
}
@Override
public int getMetricsCategory() {
return 0;
}
@Override
int getUserShortcutTypes() {
return 0;
}
@Override
public int getPreferenceScreenResId() {
return R.xml.placeholder_prefs;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return mock(View.class);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// do nothing
}
@Override
public void onDestroyView() {
// do nothing
}
@Override
public void addPreferencesFromResource(@XmlRes int preferencesResId) {
// do nothing
}
@Override
protected void updateShortcutPreference() {
// UI related function, do nothing in tests
}
} }
} }