Merge "Convert a11y shortcut edit screen to a full screen." into main

This commit is contained in:
Chun-Ku Lin
2023-12-14 22:19:08 +00:00
committed by Android (Google) Code Review
32 changed files with 3560 additions and 5 deletions

View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
import android.content.Context;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.Set;
/**
* Tests for {@link AdvancedShortcutsPreferenceController}
*/
@RunWith(RobolectricTestRunner.class)
public class AdvancedShortcutsPreferenceControllerTest {
private static final String PREF_KEY = "prefKey";
private static final String TARGET_MAGNIFICATION =
"com.android.server.accessibility.MagnificationController";
private static final String TARGET_FAKE =
new ComponentName("FakePackage", "FakeClass").flattenToString();
private final Context mContext = ApplicationProvider.getApplicationContext();
private AdvancedShortcutsPreferenceController mController;
@Before
public void setUp() {
mController = new AdvancedShortcutsPreferenceController(mContext, PREF_KEY);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
Preference preference = new Preference(mContext);
preference.setKey(PREF_KEY);
PreferenceScreen preferenceScreen =
new PreferenceManager(mContext).createPreferenceScreen(mContext);
preferenceScreen.addPreference(preference);
}
@Test
public void getAvailabilityStatus_targetIsMagnificationAndIsExpanded_returnsConditionallyUnavailable() {
mController.setExpanded(true);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_targetIsMagnificationAndIsNotExpanded_returnsAvailableUnsearchable() {
mController.setExpanded(false);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
public void getAvailabilityStatus_targetIsNotMagnificationAndIsNotExpanded_returnsConditionallyUnavailable() {
mController.setExpanded(false);
mController.setShortcutTargets(Set.of(TARGET_FAKE));
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_targetIsNotMagnificationAndIsExpanded_returnsConditionallyUnavailable() {
mController.setExpanded(true);
mController.setShortcutTargets(Set.of(TARGET_FAKE));
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void setExpanded_expand_updateExpandedValue() {
mController.setExpanded(true);
assertThat(mController.isExpanded()).isTrue();
}
@Test
public void setExpanded_collapse_updateExpandedValue() {
mController.setExpanded(false);
assertThat(mController.isExpanded()).isFalse();
}
@Test
public void isShortcutAvailable_multipleTargets_returnFalse() {
mController.setShortcutTargets(Set.of(TARGET_FAKE, TARGET_MAGNIFICATION));
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isShortcutAvailable_magnificationTargetOnly_returnTrue() {
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
assertThat(mController.isShortcutAvailable()).isTrue();
}
@Test
public void isShortcutAvailable_nonMagnificationTarget_returnFalse() {
mController.setShortcutTargets(Set.of(TARGET_FAKE));
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isChecked_returnFalse() {
assertThat(mController.isChecked()).isFalse();
}
}

View File

@@ -0,0 +1,438 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment.SHORTCUT_SETTINGS;
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_DEFERRED_SETUP;
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_FIRST_RUN;
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_PRE_DEFERRED_SETUP;
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_SETUP_FLOW;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.testing.FragmentScenario;
import androidx.lifecycle.Lifecycle;
import androidx.preference.Preference;
import androidx.preference.TwoStatePreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settings.accessibility.AccessibilityUtil;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.google.android.setupcompat.util.WizardManagerHelper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowAccessibilityManager;
import org.robolectric.shadows.ShadowContentResolver;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* Tests for {@link EditShortcutsPreferenceFragment}
*/
@Config(shadows = SettingsShadowResources.class)
@RunWith(RobolectricTestRunner.class)
public class EditShortcutsPreferenceFragmentTest {
private static final int METRICS_CATEGORY = 123;
private static final CharSequence SCREEN_TITLE = "Fake shortcut title";
private static final ComponentName TARGET_FAKE_COMPONENT =
new ComponentName("FakePackage", "FakeClass");
private static final String TARGET = MAGNIFICATION_CONTROLLER_NAME;
private static final Set<String> TARGETS = Set.of(TARGET);
private final Context mContext = ApplicationProvider.getApplicationContext();
private FragmentActivity mActivity;
private FragmentScenario<EditShortcutsPreferenceFragment> mFragmentScenario;
@Before
public void setUp() {
SettingsShadowResources.overrideResource(
com.android.internal.R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE);
mActivity = Robolectric.buildActivity(FragmentActivity.class).get();
}
@After
public void cleanUp() {
if (mFragmentScenario != null) {
mFragmentScenario.close();
}
}
@Test
public void showEditShortcutScreen_targetIsMagnification_launchSubSetting() {
EditShortcutsPreferenceFragment.showEditShortcutScreen(
mActivity, METRICS_CATEGORY, SCREEN_TITLE,
MAGNIFICATION_COMPONENT_NAME, /* fromIntent= */ null);
assertLaunchSubSettingWithCurrentTargetComponents(
MAGNIFICATION_CONTROLLER_NAME, /* isInSuw= */ false);
}
@Test
public void showEditShortcutScreen_launchSubSetting() {
EditShortcutsPreferenceFragment.showEditShortcutScreen(
mActivity, METRICS_CATEGORY, SCREEN_TITLE,
TARGET_FAKE_COMPONENT, /* fromIntent= */ null);
assertLaunchSubSettingWithCurrentTargetComponents(
TARGET_FAKE_COMPONENT.flattenToString(), /* isInSuw= */ false);
}
@Test
public void showEditShortcutScreen_inSuw_launchSubSettingWithSuw() {
EditShortcutsPreferenceFragment.showEditShortcutScreen(
mActivity, METRICS_CATEGORY, SCREEN_TITLE,
TARGET_FAKE_COMPONENT, createSuwIntent(new Intent(), /* isInSuw= */ true));
assertLaunchSubSettingWithCurrentTargetComponents(
TARGET_FAKE_COMPONENT.flattenToString(), /* isInSuw= */ true);
}
@Test
public void fragmentCreated_inSuw_controllersTargetsSet() {
mFragmentScenario = createFragScenario(/* isInSuw= */ true);
mFragmentScenario.moveToState(Lifecycle.State.CREATED);
mFragmentScenario.onFragment(fragment -> {
List<ShortcutOptionPreferenceController> controllers =
getShortcutOptionPreferenceControllers(fragment);
for (ShortcutOptionPreferenceController controller : controllers) {
assertThat(controller.getShortcutTargets()).containsExactlyElementsIn(TARGETS);
assertThat(controller.isInSetupWizard()).isTrue();
}
});
}
@Test
public void fragmentCreated_notInSuw_controllersTargetsSet() {
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.CREATED);
mFragmentScenario.onFragment(fragment -> {
List<ShortcutOptionPreferenceController> controllers =
getShortcutOptionPreferenceControllers(fragment);
for (ShortcutOptionPreferenceController controller : controllers) {
assertThat(controller.getShortcutTargets()).containsExactlyElementsIn(TARGETS);
assertThat(controller.isInSetupWizard()).isFalse();
}
});
}
@Test
public void fragmentCreated_settingsObserversAreRegistered() {
ShadowContentResolver contentResolver = shadowOf(mContext.getContentResolver());
for (Uri uri : SHORTCUT_SETTINGS) {
assertThat(contentResolver.getContentObservers(uri)).isEmpty();
}
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.CREATED);
for (Uri uri : SHORTCUT_SETTINGS) {
assertThat(contentResolver.getContentObservers(uri)).isNotEmpty();
}
}
@Test
public void fragmentDestroyed_unregisterSettingsObserver() {
ShadowContentResolver contentResolver = shadowOf(mContext.getContentResolver());
mFragmentScenario = createFragScenario(/* isInSuw= */ false)
.moveToState(Lifecycle.State.CREATED);
mFragmentScenario.onFragment(EditShortcutsPreferenceFragment::onDestroy);
for (Uri uri : SHORTCUT_SETTINGS) {
assertThat(contentResolver.getContentObservers(uri)).isEmpty();
}
}
@Test
public void onVolumeKeysShortcutSettingChanged_volumeKeyControllerUpdated() {
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.CREATED);
ShortcutUtils.optInValueToSettings(
mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);
mFragmentScenario.onFragment(fragment -> {
TwoStatePreference preference = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcut_volume_keys_pref));
assertThat(preference.isChecked()).isTrue();
});
}
@Test
public void onSoftwareShortcutSettingChanged_softwareControllersUpdated() {
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.CREATED);
ShortcutUtils.optInValueToSettings(
mContext, ShortcutConstants.UserShortcutType.SOFTWARE, TARGET);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
mFragmentScenario.onFragment(fragment -> {
TwoStatePreference preference = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcut_gesture_pref));
assertThat(preference.isChecked()).isTrue();
});
}
@Test
public void onSoftwareShortcutModeChanged_softwareControllersUpdated() {
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.CREATED);
ShortcutUtils.optInValueToSettings(
mContext, ShortcutConstants.UserShortcutType.SOFTWARE, TARGET);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
mFragmentScenario.onFragment(fragment -> {
TwoStatePreference preference = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcut_gesture_pref));
assertThat(preference.isChecked()).isTrue();
});
}
@Test
public void onTripleTapShortcutSettingChanged_tripleTapShortcutControllerUpdated() {
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.CREATED);
Settings.Secure.putInt(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
AccessibilityUtil.State.ON);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
mFragmentScenario.onFragment(fragment -> {
TwoStatePreference preference = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcut_triple_tap_pref));
assertThat(preference.isChecked()).isTrue();
});
}
@Test
public void onTwoFingersShortcutSettingChanged_twoFingersDoubleTapShortcutControllerUpdated() {
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.CREATED);
Settings.Secure.putInt(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
AccessibilityUtil.State.ON);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
mFragmentScenario.onFragment(fragment -> {
TwoStatePreference preference = fragment.findPreference(
mContext.getString(
R.string.accessibility_shortcut_two_fingers_double_tap_pref));
assertThat(preference.isChecked()).isTrue();
});
}
@Test
public void fragmentResumed_enableTouchExploration_gestureShortcutOptionSummaryUpdated() {
String expectedSummary = mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_gesture_talkback)
+ "\n\n"
+ mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_floating);
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.RESUMED);
ShadowAccessibilityManager am = shadowOf(
mContext.getSystemService(AccessibilityManager.class));
am.setTouchExplorationEnabled(true);
mFragmentScenario.onFragment(fragment -> {
Preference preference = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcut_gesture_pref));
assertThat(preference.getSummary().toString()).isEqualTo(expectedSummary);
});
}
@Test
public void fragmentPaused_enableTouchExploration_gestureShortcutOptionSummaryNotUpdated() {
String expectedSummary = mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_gesture)
+ "\n\n"
+ mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_floating);
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.RESUMED).moveToState(Lifecycle.State.STARTED);
ShadowAccessibilityManager am = shadowOf(
mContext.getSystemService(AccessibilityManager.class));
am.setTouchExplorationEnabled(true);
mFragmentScenario.onFragment(fragment -> {
Preference preference = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcut_gesture_pref));
assertThat(preference.getSummary().toString()).isEqualTo(expectedSummary);
});
}
@Test
public void onAdvancedPreferenceClicked_advancedShouldBecomeInvisible() {
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.RESUMED);
mFragmentScenario.onFragment(fragment -> {
Preference advanced = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcuts_advanced_collapsed));
assertThat(advanced.isVisible()).isTrue();
fragment.onPreferenceTreeClick(advanced);
assertThat(advanced.isVisible()).isFalse();
});
}
@Test
public void fragmentRecreated_expanded_advancedRemainInvisible() {
onAdvancedPreferenceClicked_advancedShouldBecomeInvisible();
mFragmentScenario.recreate();
mFragmentScenario.onFragment(fragment -> {
Preference advanced = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcuts_advanced_collapsed));
assertThat(advanced.isVisible()).isFalse();
});
}
@Test
public void fragmentRecreated_collapsed_advancedRemainVisible() {
mFragmentScenario = createFragScenario(/* isInSuw= */ false);
mFragmentScenario.moveToState(Lifecycle.State.RESUMED);
mFragmentScenario.recreate();
mFragmentScenario.onFragment(fragment -> {
Preference advanced = fragment.findPreference(
mContext.getString(R.string.accessibility_shortcuts_advanced_collapsed));
assertThat(advanced.isVisible()).isTrue();
});
}
private void assertLaunchSubSettingWithCurrentTargetComponents(
String componentName, boolean isInSuw) {
Intent intent = shadowOf(mActivity.getApplication()).getNextStartedActivity();
assertThat(intent).isNotNull();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
assertThat(intent.getComponent()).isEqualTo(
new ComponentName(mActivity, SubSettings.class));
assertThat(intent.getExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
.isEqualTo(EditShortcutsPreferenceFragment.class.getName());
assertThat(intent.getExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE))
.isEqualTo(SCREEN_TITLE.toString());
assertThat(intent.getExtra(
MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY)).isEqualTo(METRICS_CATEGORY);
Bundle args = (Bundle) intent.getExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
assertThat(args).isNotNull();
assertThat(Arrays.stream(args.getStringArray(
EditShortcutsPreferenceFragment.ARG_KEY_SHORTCUT_TARGETS)).toList())
.containsExactly(componentName);
assertThat(WizardManagerHelper.isAnySetupWizard(intent)).isEqualTo(isInSuw);
}
private List<ShortcutOptionPreferenceController> getShortcutOptionPreferenceControllers(
EditShortcutsPreferenceFragment fragment) {
Collection<List<AbstractPreferenceController>> controllers =
ReflectionHelpers.callInstanceMethod(fragment, "getPreferenceControllers");
List<ShortcutOptionPreferenceController> retControllers = new ArrayList<>();
controllers.stream().flatMap(Collection::stream)
.filter(controller -> controller instanceof ShortcutOptionPreferenceController)
.forEach(controller ->
retControllers.add((ShortcutOptionPreferenceController) controller));
return retControllers;
}
private FragmentScenario<EditShortcutsPreferenceFragment> createFragScenario(boolean isInSuw) {
Bundle args = new Bundle();
args.putStringArray(
EditShortcutsPreferenceFragment.ARG_KEY_SHORTCUT_TARGETS, new String[]{TARGET});
FragmentScenario<EditShortcutsPreferenceFragment> scenario =
FragmentScenario.launch(
EditShortcutsPreferenceFragment.class, args,
/* themeResId= */ 0, Lifecycle.State.INITIALIZED);
scenario.onFragment(fragment -> {
Intent intent = fragment.requireActivity().getIntent();
fragment.requireActivity().setIntent(createSuwIntent(intent, isInSuw));
// Since the fragment is attached before we have a chance
// to modify the activity's intent; initialize controllers again
fragment.initializePreferenceControllerArguments();
});
return scenario;
}
private Intent createSuwIntent(Intent intent, boolean isInSuw) {
if (intent == null) {
intent = new Intent();
}
intent.putExtra(EXTRA_IS_SETUP_FLOW, isInSuw);
intent.putExtra(EXTRA_IS_FIRST_RUN, isInSuw);
intent.putExtra(EXTRA_IS_PRE_DEFERRED_SETUP, isInSuw);
intent.putExtra(EXTRA_IS_DEFERRED_SETUP, isInSuw);
return intent;
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE;
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
import android.content.Context;
import android.provider.Settings;
import android.text.TextUtils;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.Set;
/**
* Tests for {@link FloatingButtonShortcutOptionController}
*/
@RunWith(RobolectricTestRunner.class)
public class FloatingButtonShortcutOptionControllerTest {
private static final String PREF_KEY = "prefKey";
private static final String TARGET =
new ComponentName("FakePackage", "FakeClass").flattenToString();
private final Context mContext = ApplicationProvider.getApplicationContext();
private FloatingButtonShortcutOptionController mController;
private ShortcutOptionPreference mShortcutOptionPreference;
private PreferenceScreen mPreferenceScreen;
@Before
public void setUp() {
mController = new FloatingButtonShortcutOptionController(
mContext, PREF_KEY);
mController.setShortcutTargets(Set.of(TARGET));
mShortcutOptionPreference = new ShortcutOptionPreference(mContext);
mShortcutOptionPreference.setKey(PREF_KEY);
mPreferenceScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
mPreferenceScreen.addPreference(mShortcutOptionPreference);
setFloatingButtonEnabled(true);
}
@Test
public void displayPreference_verifyTitle() {
mController.displayPreference(mPreferenceScreen);
assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo(
mContext.getString(R.string.accessibility_shortcut_edit_dialog_title_software));
}
@Test
public void getSummary_inSuw_verifySummaryEmpty() {
mController.setInSetupWizard(true);
assertThat(TextUtils.isEmpty(mController.getSummary())).isTrue();
}
@Test
public void getSummary_notInSuw_verifySummary() {
mController.setInSetupWizard(false);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_floating));
}
@Test
public void isShortcutAvailable_floatingMenuEnabled_returnTrue() {
setFloatingButtonEnabled(true);
assertThat(mController.isShortcutAvailable()).isTrue();
}
@Test
public void isShortcutAvailable_floatingMenuDisabled_returnFalse() {
setFloatingButtonEnabled(false);
assertThat(mController.isShortcutAvailable()).isFalse();
}
private void setFloatingButtonEnabled(boolean enable) {
int mode = enable
? ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU : ACCESSIBILITY_BUTTON_MODE_GESTURE;
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mode);
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.google.common.truth.Truth.assertThat;
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.Context;
import android.view.accessibility.AccessibilityManager;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.AccessibilityTestUtils;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.Set;
/**
* Tests for {@link GestureShortcutOptionController}
*/
@Config(shadows = SettingsShadowResources.class)
@RunWith(RobolectricTestRunner.class)
public class GestureShortcutOptionControllerTest {
private static final String PREF_KEY = "prefKey";
private static final String TARGET =
new ComponentName("FakePackage", "FakeClass").flattenToString();
private final Context mContext = spy(ApplicationProvider.getApplicationContext());
private GestureShortcutOptionController mController;
private ShortcutOptionPreference mShortcutOptionPreference;
private PreferenceScreen mPreferenceScreen;
@Before
public void setUp() {
mController = new GestureShortcutOptionController(
mContext, PREF_KEY);
mController.setShortcutTargets(Set.of(TARGET));
mShortcutOptionPreference = new ShortcutOptionPreference(mContext);
mShortcutOptionPreference.setKey(PREF_KEY);
mPreferenceScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
mPreferenceScreen.addPreference(mShortcutOptionPreference);
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false);
enableTouchExploration(false);
}
@Test
public void displayPreference_verifyTitle() {
mController.displayPreference(mPreferenceScreen);
assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo(
mContext.getString(
R.string.accessibility_shortcut_edit_dialog_title_software_by_gesture));
}
@Test
public void getSummary_touchExplorationDisabled_verifySummary() {
enableTouchExploration(false);
String expected = mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_gesture)
+ "\n\n"
+ mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_floating);
assertThat(mController.getSummary().toString()).isEqualTo(expected);
}
@Test
public void getSummary_touchExplorationEnabled_verifySummary() {
enableTouchExploration(true);
String expected = mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_gesture_talkback)
+ "\n\n"
+ mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_floating);
assertThat(mController.getSummary().toString()).isEqualTo(expected);
}
@Test
public void isShortcutAvailable_inSuw_returnFalse() {
mController.setInSetupWizard(true);
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isShortcutAvailable_notInSuwUseGestureNavSystemUseFab_returnFalse() {
mController.setInSetupWizard(false);
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ true);
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isShortcutAvailable_notInSuwUseGestureNavSystemNotUseFab_returnTrue() {
mController.setInSetupWizard(false);
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false);
assertThat(mController.isShortcutAvailable()).isTrue();
}
@Test
public void isShortcutAvailable_notInSuwUseButtonNavSystemUseFab_returnFalse() {
mController.setInSetupWizard(false);
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ true);
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isShortcutAvailable_notInSuwUseButtonNavSystemNotUseFab_returnFalse() {
mController.setInSetupWizard(false);
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false);
assertThat(mController.isShortcutAvailable()).isFalse();
}
private void enableTouchExploration(boolean enable) {
AccessibilityManager am = mock(AccessibilityManager.class);
when(mContext.getSystemService(AccessibilityManager.class)).thenReturn(am);
when(am.isTouchExplorationEnabled()).thenReturn(enable);
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import android.content.ComponentName;
import android.content.Context;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.AccessibilityTestUtils;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.Set;
/**
* Tests for {@link NavButtonShortcutOptionController}
*/
@Config(shadows = SettingsShadowResources.class)
@RunWith(RobolectricTestRunner.class)
public class NavButtonShortcutOptionControllerTest {
private static final String PREF_KEY = "prefKey";
private static final String TARGET =
new ComponentName("FakePackage", "FakeClass").flattenToString();
private final Context mContext = spy(ApplicationProvider.getApplicationContext());
private NavButtonShortcutOptionController mController;
private ShortcutOptionPreference mShortcutOptionPreference;
private PreferenceScreen mPreferenceScreen;
@Before
public void setUp() {
mController = new NavButtonShortcutOptionController(
mContext, PREF_KEY);
mController.setShortcutTargets(Set.of(TARGET));
mShortcutOptionPreference = new ShortcutOptionPreference(mContext);
mShortcutOptionPreference.setKey(PREF_KEY);
mPreferenceScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
mPreferenceScreen.addPreference(mShortcutOptionPreference);
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false);
}
@Test
public void displayPreference_verifyTitle() {
mController.displayPreference(mPreferenceScreen);
assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo(
mContext.getString(
R.string.accessibility_shortcut_edit_dialog_title_software));
}
@Test
public void displayPreference_inSuw_verifySummary() {
mController.setInSetupWizard(true);
mController.displayPreference(mPreferenceScreen);
assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_shortcut_edit_dialog_summary_software));
}
@Test
public void displayPreference_notInSuw_verifySummary() {
mController.setInSetupWizard(false);
String expected = mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software)
+ "\n\n"
+ mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_floating);
mController.displayPreference(mPreferenceScreen);
assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo(expected);
}
@Test
public void isShortcutAvailable_useGestureNavSystemUseFab_returnFalse() {
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ true);
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isShortcutAvailable_useGestureNavSystemNotUseFab_returnFalse() {
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false);
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isShortcutAvailable_useButtonNavSystemUseFab_returnFalse() {
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ true);
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isShortcutAvailable_useButtonNavSystemNotUseFab_returnTrue() {
AccessibilityTestUtils.setSoftwareShortcutMode(
mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false);
assertThat(mController.isShortcutAvailable()).isTrue();
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mockito;
import org.robolectric.RobolectricTestRunner;
import java.util.Set;
/**
* Tests for {@link ShortcutOptionPreferenceController}
*/
@RunWith(RobolectricTestRunner.class)
public class ShortcutOptionPreferenceControllerTest {
private static final String PREF_KEY = "prefKey";
private final Context mContext = ApplicationProvider.getApplicationContext();
private ShortcutOptionPreference mShortcutOptionPreference;
private ShortcutOptionPreferenceController mController;
@Before
public void setUp() {
mShortcutOptionPreference = spy(new ShortcutOptionPreference(mContext));
mShortcutOptionPreference.setKey(PREF_KEY);
mController = spy(new ShortcutOptionPreferenceController(mContext, PREF_KEY) {
@Override
protected boolean isShortcutAvailable() {
return false;
}
@Override
protected boolean isChecked() {
return false;
}
@Override
protected void enableShortcutForTargets(boolean enable) {
// do nothing
}
});
}
@Test
public void updateState_shortcutControllerIsChecked_shouldSetPreferenceChecked() {
when(mController.isChecked()).thenReturn(true);
mController.updateState(mShortcutOptionPreference);
assertThat(mShortcutOptionPreference.isChecked()).isTrue();
}
@Test
public void updateState_shortcutControllerIsNotChecked_shouldSetPreferenceUnchecked() {
when(mController.isChecked()).thenReturn(false);
mController.updateState(mShortcutOptionPreference);
assertThat(mShortcutOptionPreference.isChecked()).isFalse();
}
@Test
public void getAvailabilityStatus_shortcutAvailable_returnAvailableUnsearchable() {
when(mController.isShortcutAvailable()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
public void getAvailabilityStatus_shortcutUnavailable_returnConditionallyUnavailable() {
when(mController.isShortcutAvailable()).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void onPreferenceChanged_callEnableShortcutForTargets() {
mController.onPreferenceChange(mShortcutOptionPreference, true);
mController.onPreferenceChange(mShortcutOptionPreference, false);
InOrder inOrder = Mockito.inOrder(mController);
inOrder.verify(mController).enableShortcutForTargets(true);
inOrder.verify(mController).enableShortcutForTargets(false);
}
@Test
public void getShortcutTargets() {
Set<String> targets = Set.of("target1", "target2");
mController.setShortcutTargets(targets);
assertThat(mController.getShortcutTargets())
.containsExactlyElementsIn(targets);
}
@Test
public void isInSetupWizard() {
mController.setInSetupWizard(true);
assertThat(mController.isInSetupWizard()).isTrue();
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Test for {@link ShortcutOptionPreferenceTest}
*/
@RunWith(RobolectricTestRunner.class)
public class ShortcutOptionPreferenceTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private ShortcutOptionPreference mShortcutOptionPreference;
private PreferenceViewHolder mViewHolder;
private ImageView mImageView;
@Before
public void setUp() {
mShortcutOptionPreference = new ShortcutOptionPreference(mContext);
int layoutId = mShortcutOptionPreference.getLayoutResource();
View itemView = LayoutInflater.from(mContext).inflate(layoutId, /* root= */null);
mViewHolder = PreferenceViewHolder.createInstanceForTests(itemView);
mImageView = (ImageView) mViewHolder.findViewById(R.id.image);
}
@Test
public void bindViewHolder_imageResNotSet_shouldHideImageView() {
mShortcutOptionPreference.onBindViewHolder(mViewHolder);
assertThat(mImageView.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void bindViewHolder_imageResIdSet_shouldShowImageView() {
mShortcutOptionPreference.setIntroImageResId(R.drawable.a11y_shortcut_type_hardware);
mShortcutOptionPreference.onBindViewHolder(mViewHolder);
assertThat(mImageView.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void bindViewHolder_imageRawResIdSet_shouldShowImageView() {
mShortcutOptionPreference.setIntroImageRawResId(
com.android.settings.R.raw.accessibility_color_inversion_banner);
mShortcutOptionPreference.onBindViewHolder(mViewHolder);
assertThat(mImageView.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void bindViewHolder_shouldUpdateSummaryTextLineHeight() {
assertThat(mShortcutOptionPreference.getSummaryTextLineHeight()).isEqualTo(0);
mShortcutOptionPreference.onBindViewHolder(mViewHolder);
assertThat(mShortcutOptionPreference.getSummaryTextLineHeight()).isNotEqualTo(0);
}
}

View File

@@ -0,0 +1,330 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.provider.Settings;
import android.text.SpannableStringBuilder;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import androidx.fragment.app.FragmentActivity;
import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settings.accessibility.AccessibilityButtonFragment;
import com.android.settings.accessibility.FloatingMenuSizePreferenceController;
import com.android.settings.utils.AnnotationSpan;
import com.android.settingslib.accessibility.AccessibilityUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
* Tests for {@link SoftwareShortcutOptionPreferenceController}
*/
@RunWith(RobolectricTestRunner.class)
public class SoftwareShortcutOptionPreferenceControllerTest {
private static final String PREF_KEY = "prefKey";
private static final String TARGET_MAGNIFICATION =
"com.android.server.accessibility.MagnificationController";
private static final ComponentName TARGET_ALWAYS_ON_A11Y_SERVICE =
new ComponentName("FakePackage", "AlwaysOnA11yService");
private static final ComponentName TARGET_STANDARD_A11Y_SERVICE =
new ComponentName("FakePackage", "StandardA11yService");
private static final String SOFTWARE_SHORTCUT_SETTING_NAME =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
private Context mContext;
private TestSoftwareShortcutOptionPreferenceController mController;
@Before
public void setUp() {
mContext = spy(Robolectric.buildActivity(FragmentActivity.class).get());
AccessibilityServiceInfo mAlwaysOnServiceInfo = createAccessibilityServiceInfo(
TARGET_ALWAYS_ON_A11Y_SERVICE, /* isAlwaysOnService= */ true);
AccessibilityServiceInfo mStandardServiceInfo = createAccessibilityServiceInfo(
TARGET_STANDARD_A11Y_SERVICE, /* isAlwaysOnService= */ false);
AccessibilityManager am = mock(AccessibilityManager.class);
when(mContext.getSystemService(Context.ACCESSIBILITY_SERVICE)).thenReturn(am);
when(am.getInstalledAccessibilityServiceList()).thenReturn(
List.of(mAlwaysOnServiceInfo, mStandardServiceInfo));
mController = new TestSoftwareShortcutOptionPreferenceController(mContext, PREF_KEY);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
}
@Test
public void isChecked_allTargetsHasShortcutConfigured_returnTrue() {
Settings.Secure.putString(
mContext.getContentResolver(), SOFTWARE_SHORTCUT_SETTING_NAME,
String.join(String.valueOf(SERVICES_SEPARATOR),
TARGET_MAGNIFICATION,
TARGET_STANDARD_A11Y_SERVICE.flattenToString(),
TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString())
);
mController.setShortcutTargets(
Set.of(TARGET_MAGNIFICATION,
TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString(),
TARGET_STANDARD_A11Y_SERVICE.flattenToString()));
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_someTargetsHasShortcutConfigured_returnFalse() {
Settings.Secure.putString(
mContext.getContentResolver(), SOFTWARE_SHORTCUT_SETTING_NAME,
String.join(String.valueOf(SERVICES_SEPARATOR),
TARGET_MAGNIFICATION,
TARGET_STANDARD_A11Y_SERVICE.flattenToString())
);
mController.setShortcutTargets(
Set.of(TARGET_MAGNIFICATION,
TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString(),
TARGET_STANDARD_A11Y_SERVICE.flattenToString()));
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_noTargetsHasShortcutConfigured_returnFalse() {
Settings.Secure.putString(
mContext.getContentResolver(), SOFTWARE_SHORTCUT_SETTING_NAME, "");
mController.setShortcutTargets(
Set.of(TARGET_MAGNIFICATION,
TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString(),
TARGET_STANDARD_A11Y_SERVICE.flattenToString()));
assertThat(mController.isChecked()).isFalse();
}
@Test
public void getCustomizedAccessibilityButtonLink_verifyText() {
String expected =
mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_floating);
CharSequence spannable = mController.getCustomizeAccessibilityButtonLink();
assertThat(spannable.toString()).isEqualTo(expected);
}
@Test
public void getCustomizedAccessibilityButtonLink_verifyClickAction() {
String expected =
mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_software_floating);
CharSequence spannable = mController.getCustomizeAccessibilityButtonLink();
assertThat(spannable).isInstanceOf(SpannableStringBuilder.class);
AnnotationSpan[] spans = ((SpannableStringBuilder) spannable).getSpans(
0, expected.length(), AnnotationSpan.class);
spans[0].onClick(new View(mContext));
assertLaunchSettingsPage(AccessibilityButtonFragment.class.getName());
}
@Test
public void enableShortcutForTargets_enableShortcut_shortcutTurnedOn() {
String target = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
mController.setShortcutTargets(Set.of(target));
assertThat(ShortcutUtils.isComponentIdExistingInSettings(
mContext, ShortcutConstants.UserShortcutType.SOFTWARE, target
)).isFalse();
mController.enableShortcutForTargets(true);
assertThat(ShortcutUtils.isComponentIdExistingInSettings(
mContext, ShortcutConstants.UserShortcutType.SOFTWARE, target
)).isTrue();
}
@Test
public void enableShortcutForTargets_disableShortcut_shortcutTurnedOff() {
String target = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
ShortcutUtils.optInValueToSettings(
mContext, ShortcutConstants.UserShortcutType.SOFTWARE, target);
assertThat(ShortcutUtils.isComponentIdExistingInSettings(
mContext, ShortcutConstants.UserShortcutType.SOFTWARE, target
)).isTrue();
mController.setShortcutTargets(Set.of(target));
mController.enableShortcutForTargets(false);
assertThat(ShortcutUtils.isComponentIdExistingInSettings(
mContext, ShortcutConstants.UserShortcutType.SOFTWARE, target
)).isFalse();
}
@Test
public void enableShortcutForTargets_enableShortcutWithMagnification_menuSizeIncreased() {
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
mController.enableShortcutForTargets(true);
assertThat(
Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
FloatingMenuSizePreferenceController.Size.UNKNOWN))
.isEqualTo(FloatingMenuSizePreferenceController.Size.LARGE);
}
@Test
public void enableShortcutForTargets_enableShortcutWithMagnification_userConfigureSmallMenuSize_menuSizeNotChanged() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
FloatingMenuSizePreferenceController.Size.SMALL);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
mController.enableShortcutForTargets(true);
assertThat(
Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
FloatingMenuSizePreferenceController.Size.UNKNOWN))
.isEqualTo(FloatingMenuSizePreferenceController.Size.SMALL);
}
@Test
public void enableShortcutForTargets_enableAlwaysOnServiceShortcut_turnsOnAlwaysOnService() {
mController.setShortcutTargets(
Set.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()));
mController.enableShortcutForTargets(true);
assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext))
.contains(TARGET_ALWAYS_ON_A11Y_SERVICE);
}
@Test
public void enableShortcutForTargets_disableAlwaysOnServiceShortcut_turnsOffAlwaysOnService() {
mController.setShortcutTargets(
Set.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()));
mController.enableShortcutForTargets(false);
assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext))
.doesNotContain(TARGET_ALWAYS_ON_A11Y_SERVICE);
}
@Test
public void enableShortcutForTargets_enableStandardServiceShortcut_wontTurnOnService() {
mController.setShortcutTargets(
Set.of(TARGET_STANDARD_A11Y_SERVICE.flattenToString()));
mController.enableShortcutForTargets(true);
assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext))
.doesNotContain(TARGET_STANDARD_A11Y_SERVICE);
}
@Test
public void enableShortcutForTargets_disableStandardServiceShortcutWithServiceOn_wontTurnOffService() {
mController.setShortcutTargets(
Set.of(TARGET_STANDARD_A11Y_SERVICE.flattenToString()));
AccessibilityUtils.setAccessibilityServiceState(
mContext, TARGET_STANDARD_A11Y_SERVICE, /* enabled= */ true);
mController.enableShortcutForTargets(false);
assertThat(AccessibilityUtils.getEnabledServicesFromSettings(mContext))
.contains(TARGET_STANDARD_A11Y_SERVICE);
}
private void assertLaunchSettingsPage(String page) {
ContextWrapper applicationContext = (Application) mContext.getApplicationContext();
final Intent intent = Shadows.shadowOf(applicationContext).getNextStartedActivity();
assertThat(intent).isNotNull();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MAIN);
assertThat(intent.getComponent()).isEqualTo(
new ComponentName(applicationContext, SubSettings.class));
assertThat(intent.getExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(page);
}
private AccessibilityServiceInfo createAccessibilityServiceInfo(
ComponentName componentName, boolean isAlwaysOnService) {
final ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
final ServiceInfo serviceInfo = new ServiceInfo();
applicationInfo.packageName = componentName.getPackageName();
serviceInfo.packageName = componentName.getPackageName();
serviceInfo.name = componentName.getClassName();
serviceInfo.applicationInfo = applicationInfo;
final ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.serviceInfo = serviceInfo;
try {
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
mContext);
info.setComponentName(componentName);
if (isAlwaysOnService) {
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
}
return info;
} catch (XmlPullParserException | IOException e) {
// Do nothing
}
return null;
}
private static class TestSoftwareShortcutOptionPreferenceController
extends SoftwareShortcutOptionPreferenceController {
TestSoftwareShortcutOptionPreferenceController(
Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
protected boolean isShortcutAvailable() {
return true;
}
}
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
import android.content.Context;
import android.icu.text.MessageFormat;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.Set;
/**
* Tests for {@link TripleTapShortcutOptionController}
*/
@RunWith(RobolectricTestRunner.class)
public class TripleTapShortcutOptionControllerTest {
private static final String PREF_KEY = "prefKey";
private static final String TARGET_MAGNIFICATION =
"com.android.server.accessibility.MagnificationController";
private static final String TARGET_FAKE =
new ComponentName("FakePackage", "FakeClass").flattenToString();
private final Context mContext = ApplicationProvider.getApplicationContext();
private TripleTapShortcutOptionController mController;
private ShortcutOptionPreference mShortcutOptionPreference;
private PreferenceScreen mPreferenceScreen;
@Before
public void setUp() {
mController = new TripleTapShortcutOptionController(mContext, PREF_KEY);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
mShortcutOptionPreference = new ShortcutOptionPreference(mContext);
mShortcutOptionPreference.setKey(PREF_KEY);
mPreferenceScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
mPreferenceScreen.addPreference(mShortcutOptionPreference);
}
@Test
public void displayPreference_verifyScreenTestSet() {
mController.displayPreference(mPreferenceScreen);
assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo(
mContext.getString(R.string.accessibility_shortcut_edit_dialog_title_triple_tap));
assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo(
MessageFormat.format(
mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_triple_tap),
3));
}
@Test
public void getAvailabilityStatus_targetIsMagnificationAndIsExpanded_returnsAvailableUnsearchable() {
mController.setExpanded(true);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
public void getAvailabilityStatus_targetIsMagnificationAndIsNotExpanded_returnsConditionallyUnavailable() {
mController.setExpanded(false);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_targetIsNotMagnificationAndIsNotExpanded_returnsConditionallyUnavailable() {
mController.setExpanded(false);
mController.setShortcutTargets(Set.of(TARGET_FAKE));
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_targetIsNotMagnificationAndIsExpanded_returnsConditionallyUnavailable() {
mController.setExpanded(true);
mController.setShortcutTargets(Set.of(TARGET_FAKE));
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void setExpanded_expand_updateExpandedValue() {
mController.setExpanded(true);
assertThat(mController.isExpanded()).isTrue();
}
@Test
public void setExpanded_collapse_updateExpandedValue() {
mController.setExpanded(false);
assertThat(mController.isExpanded()).isFalse();
}
@Test
public void isShortcutAvailable_multipleTargets_returnFalse() {
mController.setShortcutTargets(Set.of(TARGET_FAKE, TARGET_MAGNIFICATION));
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isShortcutAvailable_magnificationTargetOnly_returnTrue() {
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
assertThat(mController.isShortcutAvailable()).isTrue();
}
@Test
public void isShortcutAvailable_nonMagnificationTarget_returnFalse() {
mController.setShortcutTargets(Set.of(TARGET_FAKE));
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isChecked_tripleTapConfigured_returnTrue() {
mController.enableShortcutForTargets(true);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_tripleTapNotConfigured_returnFalse() {
mController.enableShortcutForTargets(false);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void enableShortcutForTargets_enableShortcut_settingUpdated() {
mController.enableShortcutForTargets(true);
assertThat(
Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
AccessibilityUtil.State.OFF)
).isEqualTo(AccessibilityUtil.State.ON);
}
@Test
public void enableShortcutForTargets_disableShortcut_settingUpdated() {
mController.enableShortcutForTargets(false);
assertThat(
Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
AccessibilityUtil.State.OFF)
).isEqualTo(AccessibilityUtil.State.OFF);
}
}

View File

@@ -0,0 +1,154 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
import android.content.Context;
import android.icu.text.MessageFormat;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.server.accessibility.Flags;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.Set;
/**
* Tests for {@link TwoFingersDoubleTapShortcutOptionController}
*/
@RunWith(RobolectricTestRunner.class)
public class TwoFingersDoubleTapShortcutOptionControllerTest {
private static final String PREF_KEY = "prefKey";
private static final String TARGET_MAGNIFICATION =
"com.android.server.accessibility.MagnificationController";
private static final String TARGET_FAKE =
new ComponentName("FakePackage", "FakeClass").flattenToString();
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private TwoFingersDoubleTapShortcutOptionController mController;
private ShortcutOptionPreference mShortcutOptionPreference;
private PreferenceScreen mPreferenceScreen;
@Before
public void setUp() {
mController = new TwoFingersDoubleTapShortcutOptionController(mContext, PREF_KEY);
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
mShortcutOptionPreference = new ShortcutOptionPreference(mContext);
mShortcutOptionPreference.setKey(PREF_KEY);
mPreferenceScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
mPreferenceScreen.addPreference(mShortcutOptionPreference);
}
@Test
public void displayPreference_verifyScreenTextSet() {
mController.displayPreference(mPreferenceScreen);
assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo(
mContext.getString(
R.string.accessibility_shortcut_edit_dialog_title_two_finger_double_tap));
assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo(
MessageFormat.format(mContext.getString(
R.string.accessibility_shortcut_edit_dialog_summary_two_finger_double_tap),
2));
}
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
@Test
public void isShortcutAvailable_featureFlagTurnedOff_returnFalse() {
assertThat(mController.isShortcutAvailable()).isFalse();
}
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
@Test
public void isShortcutAvailable_multipleTargets_returnFalse() {
mController.setShortcutTargets(Set.of(TARGET_FAKE, TARGET_MAGNIFICATION));
assertThat(mController.isShortcutAvailable()).isFalse();
}
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
@Test
public void isShortcutAvailable_magnificationTargetOnly_returnTrue() {
mController.setShortcutTargets(Set.of(TARGET_MAGNIFICATION));
assertThat(mController.isShortcutAvailable()).isTrue();
}
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
@Test
public void isShortcutAvailable_nonMagnificationTarget_returnFalse() {
mController.setShortcutTargets(Set.of(TARGET_FAKE));
assertThat(mController.isShortcutAvailable()).isFalse();
}
@Test
public void isChecked_twoFingersDoubleTapConfigured_returnTrue() {
mController.enableShortcutForTargets(true);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_twoFingersDoubleTapNotConfigured_returnFalse() {
mController.enableShortcutForTargets(false);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void enableShortcutForTargets_enableShortcut_settingUpdated() {
mController.enableShortcutForTargets(true);
assertThat(
Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
AccessibilityUtil.State.OFF)
).isEqualTo(AccessibilityUtil.State.ON);
}
@Test
public void enableShortcutForTargets_disableShortcut_settingUpdated() {
mController.enableShortcutForTargets(false);
assertThat(
Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
AccessibilityUtil.State.OFF)
).isEqualTo(AccessibilityUtil.State.OFF);
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) 2023 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.shortcuts;
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
import android.content.Context;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.Set;
/**
* Tests for {@link VolumeKeysShortcutOptionController}
*/
@RunWith(RobolectricTestRunner.class)
public class VolumeKeysShortcutOptionControllerTest {
private static final String PREF_KEY = "prefKey";
private static final String TARGET =
new ComponentName("FakePackage", "FakeClass").flattenToString();
private final Context mContext = ApplicationProvider.getApplicationContext();
private VolumeKeysShortcutOptionController mController;
private ShortcutOptionPreference mShortcutOptionPreference;
private PreferenceScreen mPreferenceScreen;
@Before
public void setUp() {
mController = new VolumeKeysShortcutOptionController(
mContext, PREF_KEY);
mController.setShortcutTargets(Set.of(TARGET));
mShortcutOptionPreference = new ShortcutOptionPreference(mContext);
mShortcutOptionPreference.setKey(PREF_KEY);
mPreferenceScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
mPreferenceScreen.addPreference(mShortcutOptionPreference);
}
@Test
public void displayPreference_verifyScreenTextSet() {
mController.displayPreference(mPreferenceScreen);
assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo(
mContext.getString(R.string.accessibility_shortcut_edit_dialog_title_hardware));
assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_shortcut_edit_dialog_summary_hardware));
}
@Test
public void isShortcutAvailable_returnsTrue() {
assertThat(mController.isShortcutAvailable()).isTrue();
}
@Test
public void isChecked_targetUseVolumeKeyShortcut_returnTrue() {
ShortcutUtils.optInValueToSettings(
mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_targetNotUseVolumeKeyShortcut_returnFalse() {
ShortcutUtils.optOutValueFromSettings(
mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void enableShortcutForTargets_enableVolumeKeysShortcut_shortcutSet() {
mController.enableShortcutForTargets(true);
assertThat(
ShortcutUtils.isComponentIdExistingInSettings(
mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET)).isTrue();
}
@Test
public void enableShortcutForTargets_disableVolumeKeysShortcut_shortcutNotSet() {
mController.enableShortcutForTargets(false);
assertThat(
ShortcutUtils.isComponentIdExistingInSettings(
mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET)).isFalse();
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2023 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.testutils;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.testutils.shadow.SettingsShadowResources;
/**
* Utility class for common methods used in the accessibility feature related tests
*/
public class AccessibilityTestUtils {
public static void setSoftwareShortcutMode(
Context context, boolean gestureNavEnabled, boolean floatingButtonEnabled) {
int mode = floatingButtonEnabled ? ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU : -1;
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mode);
if (gestureNavEnabled) {
SettingsShadowResources.overrideResource(
com.android.internal.R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_GESTURAL);
} else {
SettingsShadowResources.overrideResource(
com.android.internal.R.integer.config_navBarInteractionMode,
NAV_BAR_MODE_3BUTTON);
}
}
}