Support OHM quick settings tooltips when feature on
Bug: 210356011 Test: make RunSettingsRoboTests ROBOTEST_FILTER=AccessibilityShortcutPreferenceFragmentTest Change-Id: I3b35d9bb347b7e516db94a4b801a4484f6f38ca8
This commit is contained in:
@@ -28,6 +28,7 @@ import android.icu.text.CaseMap;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -56,6 +57,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends DashboardF
|
||||
implements ShortcutPreference.OnClickCallback {
|
||||
private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
|
||||
protected static final String KEY_SAVED_USER_SHORTCUT_TYPE = "shortcut_type";
|
||||
protected static final String KEY_SAVED_QS_TOOLTIP_RESHOW = "qs_tooltip_reshow";
|
||||
protected static final int NOT_SET = -1;
|
||||
// Save user's shortcutType value when savedInstance has value (e.g. device rotated).
|
||||
protected int mSavedCheckBoxValue = NOT_SET;
|
||||
@@ -66,6 +68,8 @@ public abstract class AccessibilityShortcutPreferenceFragment extends DashboardF
|
||||
private AccessibilitySettingsContentObserver mSettingsContentObserver;
|
||||
private CheckBox mSoftwareTypeCheckBox;
|
||||
private CheckBox mHardwareTypeCheckBox;
|
||||
private AccessibilityQuickSettingsTooltipWindow mTooltipWindow;
|
||||
private boolean mNeedsQSTooltipReshow = false;
|
||||
|
||||
/** Returns the accessibility component name. */
|
||||
protected abstract ComponentName getComponentName();
|
||||
@@ -73,14 +77,25 @@ public abstract class AccessibilityShortcutPreferenceFragment extends DashboardF
|
||||
/** Returns the accessibility feature name. */
|
||||
protected abstract CharSequence getLabelName();
|
||||
|
||||
/** Returns the accessibility tile component name. */
|
||||
protected abstract ComponentName getTileComponentName();
|
||||
|
||||
/** Returns the accessibility tile feature name. */
|
||||
protected abstract CharSequence getTileName();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Restore the user shortcut type.
|
||||
if (savedInstanceState != null && savedInstanceState.containsKey(
|
||||
KEY_SAVED_USER_SHORTCUT_TYPE)) {
|
||||
mSavedCheckBoxValue = savedInstanceState.getInt(KEY_SAVED_USER_SHORTCUT_TYPE, NOT_SET);
|
||||
// Restore the user shortcut type and tooltip.
|
||||
if (savedInstanceState != null) {
|
||||
if (savedInstanceState.containsKey(KEY_SAVED_USER_SHORTCUT_TYPE)) {
|
||||
mSavedCheckBoxValue = savedInstanceState.getInt(KEY_SAVED_USER_SHORTCUT_TYPE,
|
||||
NOT_SET);
|
||||
}
|
||||
if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_RESHOW)) {
|
||||
mNeedsQSTooltipReshow = savedInstanceState.getBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW);
|
||||
}
|
||||
}
|
||||
|
||||
final int resId = getPreferenceScreenResId();
|
||||
@@ -123,6 +138,16 @@ public abstract class AccessibilityShortcutPreferenceFragment extends DashboardF
|
||||
return super.onCreateView(inflater, container, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// Reshow tooltips when activity recreate, such as rotate device.
|
||||
if (mNeedsQSTooltipReshow) {
|
||||
getView().post(this::showQuickSettingsTooltipIfNeeded);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
@@ -149,6 +174,9 @@ public abstract class AccessibilityShortcutPreferenceFragment extends DashboardF
|
||||
if (value != NOT_SET) {
|
||||
outState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE, value);
|
||||
}
|
||||
if (mTooltipWindow != null) {
|
||||
outState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, mTooltipWindow.isShowing());
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@@ -423,4 +451,33 @@ public abstract class AccessibilityShortcutPreferenceFragment extends DashboardF
|
||||
getComponentName()));
|
||||
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
|
||||
}
|
||||
|
||||
protected void showQuickSettingsTooltipIfNeeded() {
|
||||
final ComponentName tileComponentName = getTileComponentName();
|
||||
if (tileComponentName == null) {
|
||||
// Returns if no tile service assigned.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mNeedsQSTooltipReshow && AccessibilityQuickSettingUtils.hasValueInSharedPreferences(
|
||||
getContext(), tileComponentName)) {
|
||||
// Returns if quick settings tooltip only show once.
|
||||
return;
|
||||
}
|
||||
|
||||
final CharSequence tileName = getTileName();
|
||||
if (TextUtils.isEmpty(tileName)) {
|
||||
// Returns if no title of tile service assigned.
|
||||
return;
|
||||
}
|
||||
|
||||
final String title =
|
||||
getString(R.string.accessibility_service_quick_settings_tooltips_content, tileName);
|
||||
mTooltipWindow = new AccessibilityQuickSettingsTooltipWindow(getContext());
|
||||
mTooltipWindow.setup(title);
|
||||
mTooltipWindow.showAtTopCenter(getView());
|
||||
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(getContext(),
|
||||
tileComponentName);
|
||||
mNeedsQSTooltipReshow = false;
|
||||
}
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragmen
|
||||
import com.android.settings.accessibility.ShortcutPreference;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.widget.IllustrationPreference;
|
||||
import com.android.settingslib.widget.MainSwitchPreference;
|
||||
|
||||
/**
|
||||
* Fragment for One-handed mode settings
|
||||
@@ -40,6 +41,8 @@ public class OneHandedSettings extends AccessibilityShortcutPreferenceFragment {
|
||||
|
||||
private static final String ONE_HANDED_SHORTCUT_KEY = "one_handed_shortcuts_preference";
|
||||
private static final String ONE_HANDED_ILLUSTRATION_KEY = "one_handed_header";
|
||||
protected static final String ONE_HANDED_MAIN_SWITCH_KEY =
|
||||
"gesture_one_handed_mode_enabled_main_switch";
|
||||
private String mFeatureName;
|
||||
private OneHandedSettingsUtils mUtils;
|
||||
|
||||
@@ -48,16 +51,22 @@ public class OneHandedSettings extends AccessibilityShortcutPreferenceFragment {
|
||||
OneHandedSettingsUtils.setUserId(UserHandle.myUserId());
|
||||
super.updatePreferenceStates();
|
||||
|
||||
final IllustrationPreference preference =
|
||||
(IllustrationPreference) getPreferenceScreen().findPreference(
|
||||
ONE_HANDED_ILLUSTRATION_KEY);
|
||||
if (preference != null) {
|
||||
final boolean isSwipeDownNotification =
|
||||
OneHandedSettingsUtils.isSwipeDownNotificationEnabled(getContext());
|
||||
preference.setLottieAnimationResId(
|
||||
isSwipeDownNotification ? R.raw.lottie_swipe_for_notifications
|
||||
: R.raw.lottie_one_hand_mode);
|
||||
}
|
||||
final IllustrationPreference illustrationPreference =
|
||||
getPreferenceScreen().findPreference(ONE_HANDED_ILLUSTRATION_KEY);
|
||||
final boolean isSwipeDownNotification =
|
||||
OneHandedSettingsUtils.isSwipeDownNotificationEnabled(getContext());
|
||||
illustrationPreference.setLottieAnimationResId(
|
||||
isSwipeDownNotification ? R.raw.lottie_swipe_for_notifications
|
||||
: R.raw.lottie_one_hand_mode);
|
||||
|
||||
final MainSwitchPreference mainSwitchPreference =
|
||||
getPreferenceScreen().findPreference(ONE_HANDED_MAIN_SWITCH_KEY);
|
||||
mainSwitchPreference.addOnSwitchChangeListener((switchView, isChecked) -> {
|
||||
switchView.setChecked(isChecked);
|
||||
if (isChecked) {
|
||||
showQuickSettingsTooltipIfNeeded();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,6 +124,16 @@ public class OneHandedSettings extends AccessibilityShortcutPreferenceFragment {
|
||||
return mFeatureName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ComponentName getTileComponentName() {
|
||||
return AccessibilityShortcutController.ONE_HANDED_TILE_COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence getTileName() {
|
||||
return mFeatureName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.one_handed_settings;
|
||||
|
@@ -16,11 +16,14 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_QS_TOOLTIP_RESHOW;
|
||||
import static com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_USER_SHORTCUT_TYPE;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||
|
||||
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.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -30,6 +33,10 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@@ -48,6 +55,8 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
/** Tests for {@link AccessibilityShortcutPreferenceFragment} */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -55,8 +64,12 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
|
||||
private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
|
||||
private static final String PLACEHOLDER_CLASS_NAME = PLACEHOLDER_PACKAGE_NAME + ".placeholder";
|
||||
private static final String PLACEHOLDER_TILE_CLASS_NAME =
|
||||
PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
|
||||
private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
|
||||
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
|
||||
private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
|
||||
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
|
||||
private static final String PLACEHOLDER_DIALOG_TITLE = "title";
|
||||
|
||||
private static final String SOFTWARE_SHORTCUT_KEY =
|
||||
@@ -89,10 +102,9 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
mFragment.getComponentName().flattenToString(), UserShortcutType.SOFTWARE);
|
||||
// Compare to default UserShortcutType
|
||||
assertThat(expectedType).isEqualTo(AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,25 +115,21 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(AccessibilityUtil.UserShortcutType.SOFTWARE
|
||||
| AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
mFragment.getComponentName().flattenToString(), UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable() {
|
||||
final PreferredShortcut hardwareShortcut = new PreferredShortcut(
|
||||
PLACEHOLDER_COMPONENT_NAME.flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
|
||||
|
||||
putUserShortcutTypeIntoSharedPreference(mContext, hardwareShortcut);
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
mFragment.getComponentName().flattenToString(), UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -139,7 +147,7 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
|
||||
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
|
||||
assertThat(checkboxValue).isEqualTo(AccessibilityUtil.UserShortcutType.EMPTY);
|
||||
assertThat(checkboxValue).isEqualTo(UserShortcutType.EMPTY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -152,8 +160,7 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
null);
|
||||
final PreferredShortcut hardwareShortcut = new PreferredShortcut(
|
||||
PLACEHOLDER_COMPONENT_NAME.flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
|
||||
mFragment.mShortcutPreference = shortcutPreference;
|
||||
|
||||
PreferredShortcuts.saveUserShortcutType(mContext, hardwareShortcut);
|
||||
@@ -161,12 +168,12 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
|
||||
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
|
||||
assertThat(checkboxValue).isEqualTo(AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
assertThat(checkboxValue).isEqualTo(UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void restoreValueFromSavedInstanceState_assignToVariable() {
|
||||
public void restoreValueFromSavedInstanceState_assignShortcutTypeToVariable() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
|
||||
@@ -178,8 +185,7 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
mFragment.mShortcutPreference = shortcutPreference;
|
||||
|
||||
savedInstanceState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE,
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE
|
||||
| AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(savedInstanceState);
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
@@ -187,11 +193,25 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
mFragment.saveNonEmptyUserShortcutType(value);
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE
|
||||
| AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
mFragment.getComponentName().flattenToString(), UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void restoreValueFromSavedInstanceState_showTooltipView() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
mFragment.showQuickSettingsTooltipIfNeeded();
|
||||
assertThat(getLatestPopupWindow().isShowing()).isTrue();
|
||||
|
||||
final Bundle savedInstanceState = new Bundle();
|
||||
savedInstanceState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(savedInstanceState);
|
||||
mFragment.onCreateView(LayoutInflater.from(mContext), mock(ViewGroup.class), Bundle.EMPTY);
|
||||
mFragment.onViewCreated(mFragment.getView(), savedInstanceState);
|
||||
|
||||
assertThat(getLatestPopupWindow().isShowing()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -221,8 +241,26 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
PreferredShortcuts.saveUserShortcutType(context, shortcut);
|
||||
}
|
||||
|
||||
private static PopupWindow getLatestPopupWindow() {
|
||||
final ShadowApplication shadowApplication =
|
||||
Shadow.extract(ApplicationProvider.getApplicationContext());
|
||||
return shadowApplication.getLatestPopupWindow();
|
||||
}
|
||||
|
||||
public static class TestAccessibilityShortcutPreferenceFragment
|
||||
extends AccessibilityShortcutPreferenceFragment {
|
||||
|
||||
@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
|
||||
protected ComponentName getComponentName() {
|
||||
return PLACEHOLDER_COMPONENT_NAME;
|
||||
@@ -233,6 +271,16 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
return PLACEHOLDER_PACKAGE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ComponentName getTileComponentName() {
|
||||
return PLACEHOLDER_TILE_COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence getTileName() {
|
||||
return PLACEHOLDER_PACKAGE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUserShortcutTypes() {
|
||||
return 0;
|
||||
@@ -263,5 +311,10 @@ public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
protected String getLogTag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return mock(View.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user