From 7d4312596428e2a629da73f5a5524a6eda9da8db Mon Sep 17 00:00:00 2001 From: Mehdi Alizadeh Date: Wed, 22 May 2019 11:22:45 -0700 Subject: [PATCH] Show a dialog with a slider to set the back gesture's sensitivity Bug: 131447780 Test: Manual test on device Test: make RunSettingsRoboTests ROBOTEST_FILTER=RadioButtonPreferenceWithExtraWidgetTest Test: make RunSettingsRoboTests ROBOTEST_FILTER=SystemNavigationGestureSettingsTest Change-Id: I9fcd1a50c77689118857326de0cf8082e835b491 --- .../dialog_back_gesture_sensitivity.xml | 67 ++++++++ res/values/dimens.xml | 3 + res/values/strings.xml | 11 ++ ...estureNavigationBackSensitivityDialog.java | 81 ++++++++++ .../GestureNavigationNotAvailableDialog.java | 63 ++++++++ .../SystemNavigationGestureSettings.java | 150 ++++++++++++------ .../RadioButtonPreferenceWithExtraWidget.java | 10 ++ .../SystemNavigationGestureSettingsTest.java | 146 ++++++++++++++--- ...ioButtonPreferenceWithExtraWidgetTest.java | 13 ++ 9 files changed, 470 insertions(+), 74 deletions(-) create mode 100644 res/layout/dialog_back_gesture_sensitivity.xml create mode 100644 src/com/android/settings/gestures/GestureNavigationBackSensitivityDialog.java create mode 100644 src/com/android/settings/gestures/GestureNavigationNotAvailableDialog.java diff --git a/res/layout/dialog_back_gesture_sensitivity.xml b/res/layout/dialog_back_gesture_sensitivity.xml new file mode 100644 index 00000000000..37ef7714137 --- /dev/null +++ b/res/layout/dialog_back_gesture_sensitivity.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index fbf1a24d7a9..f31a2667ca5 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -411,4 +411,7 @@ 480dp + + + 320dp diff --git a/res/values/strings.xml b/res/values/strings.xml index 6e92a3d6613..6df98f118ef 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10225,6 +10225,17 @@ Information + + Low + + High + + + \nHigher sensitivity may conflict with any app gestures along the edges of the screen. + + + Back Sensitivity + Double-tap to check phone diff --git a/src/com/android/settings/gestures/GestureNavigationBackSensitivityDialog.java b/src/com/android/settings/gestures/GestureNavigationBackSensitivityDialog.java new file mode 100644 index 00000000000..164705bfe65 --- /dev/null +++ b/src/com/android/settings/gestures/GestureNavigationBackSensitivityDialog.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 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.gestures; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.content.om.IOverlayManager; +import android.os.Bundle; +import android.os.ServiceManager; +import android.view.View; +import android.widget.SeekBar; + +import com.android.settings.R; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; + +/** + * Dialog to set the back gesture's sensitivity in Gesture navigation mode. + */ +public class GestureNavigationBackSensitivityDialog extends InstrumentedDialogFragment { + private static final String TAG = "GestureNavigationBackSensitivityDialog"; + private static final String KEY_BACK_SENSITIVITY = "back_sensitivity"; + + public static void show(SystemNavigationGestureSettings parent, int sensitivity) { + if (!parent.isAdded()) { + return; + } + + final GestureNavigationBackSensitivityDialog dialog = + new GestureNavigationBackSensitivityDialog(); + final Bundle bundle = new Bundle(); + bundle.putInt(KEY_BACK_SENSITIVITY, sensitivity); + dialog.setArguments(bundle); + dialog.setTargetFragment(parent, 0); + dialog.show(parent.getFragmentManager(), TAG); + } + + @Override + public int getMetricsCategory() { + // TODO(135211145): Use a separate metrics category for this dialog. + return SettingsEnums.SETTINGS_GESTURE_SWIPE_UP; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final View view = getActivity().getLayoutInflater().inflate( + R.layout.dialog_back_gesture_sensitivity, null); + final SeekBar seekBar = view.findViewById(R.id.back_sensitivity_seekbar); + seekBar.setProgress(getArguments().getInt(KEY_BACK_SENSITIVITY)); + return new AlertDialog.Builder(getContext()) + .setTitle(R.string.back_sensitivity_dialog_title) + .setMessage(R.string.back_sensitivity_dialog_message) + .setView(view) + .setPositiveButton(R.string.okay, (dialog, which) -> { + int sensitivity = seekBar.getProgress(); + getArguments().putInt(KEY_BACK_SENSITIVITY, sensitivity); + SystemNavigationGestureSettings.setBackSensitivity(getActivity(), + getOverlayManager(), sensitivity); + }) + .create(); + } + + private IOverlayManager getOverlayManager() { + return IOverlayManager.Stub.asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)); + } +} \ No newline at end of file diff --git a/src/com/android/settings/gestures/GestureNavigationNotAvailableDialog.java b/src/com/android/settings/gestures/GestureNavigationNotAvailableDialog.java new file mode 100644 index 00000000000..e69db274011 --- /dev/null +++ b/src/com/android/settings/gestures/GestureNavigationNotAvailableDialog.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 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.gestures; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.os.Bundle; + +import com.android.settings.R; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; + +/** + * Dialog to notify user that gesture navigation is not available because of unsupported launcher. + */ +public class GestureNavigationNotAvailableDialog extends InstrumentedDialogFragment { + private static final String TAG = "GestureNavigationNotAvailableDialog"; + + public static void show(SystemNavigationGestureSettings parent) { + if (!parent.isAdded()) { + return; + } + + final GestureNavigationNotAvailableDialog dialog = + new GestureNavigationNotAvailableDialog(); + dialog.setTargetFragment(parent, 0); + dialog.show(parent.getFragmentManager(), TAG); + } + + @Override + public int getMetricsCategory() { + // TODO(135211145): Use a separate metrics category for this dialog. + return SettingsEnums.SETTINGS_GESTURE_SWIPE_UP; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Context context = getActivity(); + final String defaultHomeAppName = SystemNavigationPreferenceController + .getDefaultHomeAppName(context); + final String message = getString(R.string.gesture_not_supported_dialog_message, + defaultHomeAppName); + return new AlertDialog.Builder(context) + .setMessage(message) + .setPositiveButton(R.string.okay, null) + .create(); + } +} \ No newline at end of file diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java index 28b76b2b011..b3d090d75f2 100644 --- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java +++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java @@ -23,14 +23,15 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OV import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE; import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_INFO; +import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING; -import android.app.AlertDialog; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.om.IOverlayManager; +import android.content.om.OverlayInfo; import android.graphics.drawable.Drawable; import android.os.RemoteException; import android.os.ServiceManager; @@ -64,6 +65,11 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { private static final String TAG = "SystemNavigationGesture"; + @VisibleForTesting + static final String SHARED_PREFERENCES_NAME = "system_navigation_settings_preferences"; + @VisibleForTesting + static final String PREFS_BACK_SENSITIVITY_KEY = "system_navigation_back_sensitivity"; + @VisibleForTesting static final String KEY_SYSTEM_NAV_3BUTTONS = "system_nav_3buttons"; @VisibleForTesting @@ -74,6 +80,25 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { public static final String PREF_KEY_SUGGESTION_COMPLETE = "pref_system_navigation_suggestion_complete"; + @VisibleForTesting + static final String NAV_BAR_MODE_GESTURAL_OVERLAY_NARROW_BACK + = "com.android.internal.systemui.navbar.gestural_narrow_back"; + @VisibleForTesting + static final String NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK + = "com.android.internal.systemui.navbar.gestural_wide_back"; + @VisibleForTesting + static final String NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK + = "com.android.internal.systemui.navbar.gestural_extra_wide_back"; + @VisibleForTesting + static final String[] BACK_GESTURE_INSET_OVERLAYS = { + NAV_BAR_MODE_GESTURAL_OVERLAY_NARROW_BACK, + NAV_BAR_MODE_GESTURAL_OVERLAY, + NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK, + NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK + }; + @VisibleForTesting + static int BACK_GESTURE_INSET_DEFAULT_OVERLAY = 1; + private IOverlayManager mOverlayManager; private VideoPreference mVideoPreference; @@ -91,6 +116,9 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { mVideoPreference = new VideoPreference(context); setIllustrationVideo(mVideoPreference, getDefaultKey()); + mVideoPreference.setHeight( /* Illustration height in dp */ + getResources().getDimension(R.dimen.system_navigation_illustration_height) + / getResources().getDisplayMetrics().density); } @Override @@ -98,11 +126,6 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { return SettingsEnums.SETTINGS_GESTURE_SWIPE_UP; } - @Override - protected int getPreferenceScreenResId() { - return R.xml.system_navigation_gesture_settings; - } - @Override public void updateCandidates() { final String defaultKey = getDefaultKey(); @@ -125,6 +148,39 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { mayCheckOnlyRadioButton(); } + @Override + public void bindPreferenceExtra(RadioButtonPreference pref, + String key, CandidateInfo info, String defaultKey, String systemDefaultKey) { + if (!(info instanceof NavModeCandidateInfo) + || !(pref instanceof RadioButtonPreferenceWithExtraWidget)) { + return; + } + + pref.setSummary(((NavModeCandidateInfo) info).loadSummary()); + + RadioButtonPreferenceWithExtraWidget p = (RadioButtonPreferenceWithExtraWidget) pref; + if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL) { + if (SystemNavigationPreferenceController.isGestureNavSupportedByDefaultLauncher( + getContext())) { + p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING); + p.setExtraWidgetOnClickListener((v) -> GestureNavigationBackSensitivityDialog + .show(this, getBackSensitivity(getContext(), mOverlayManager))); + } else { + p.setEnabled(false); + p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_INFO); + p.setExtraWidgetOnClickListener((v) -> + GestureNavigationNotAvailableDialog.show(this)); + } + } else { + p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE); + } + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.system_navigation_gesture_settings; + } + @Override protected List getCandidates() { final Context c = getContext(); @@ -169,7 +225,7 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { return false; } - setCurrentSystemNavigationMode(mOverlayManager, key); + setCurrentSystemNavigationMode(c, mOverlayManager, key); setIllustrationVideo(mVideoPreference, key); if (TextUtils.equals(KEY_SYSTEM_NAV_GESTURAL, key) && ( isAnyServiceSupportAccessibilityButton() || isNavBarMagnificationEnabled())) { @@ -180,6 +236,37 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { return true; } + @VisibleForTesting + static void setBackSensitivity(Context context, IOverlayManager overlayManager, + int sensitivity) { + if (sensitivity < 0 || sensitivity >= BACK_GESTURE_INSET_OVERLAYS.length) { + throw new IllegalArgumentException("Sensitivity out of range."); + } + + // Store the sensitivity level, to be able to restore when user returns to Gesture Nav mode + context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).edit() + .putInt(PREFS_BACK_SENSITIVITY_KEY, sensitivity).apply(); + if (getCurrentSystemNavigationMode(context) == KEY_SYSTEM_NAV_GESTURAL) { + setNavBarInteractionMode(overlayManager, BACK_GESTURE_INSET_OVERLAYS[sensitivity]); + } + } + + @VisibleForTesting + static int getBackSensitivity(Context context, IOverlayManager overlayManager) { + for (int i = 0; i < BACK_GESTURE_INSET_OVERLAYS.length; i++) { + OverlayInfo info = null; + try { + info = overlayManager.getOverlayInfo(BACK_GESTURE_INSET_OVERLAYS[i], USER_CURRENT); + } catch (RemoteException e) { /* Do nothing */ } + if (info != null && info.isEnabled()) { + return i; + } + } + // If Gesture nav is not selected, read the value from shared preferences. + return context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE) + .getInt(PREFS_BACK_SENSITIVITY_KEY, BACK_GESTURE_INSET_DEFAULT_OVERLAY); + } + @VisibleForTesting static String getCurrentSystemNavigationMode(Context context) { if (SystemNavigationPreferenceController.isEdgeToEdgeEnabled(context)) { @@ -192,10 +279,12 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { } @VisibleForTesting - static void setCurrentSystemNavigationMode(IOverlayManager overlayManager, String key) { + static void setCurrentSystemNavigationMode(Context context, IOverlayManager overlayManager, + String key) { switch (key) { case KEY_SYSTEM_NAV_GESTURAL: - setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_GESTURAL_OVERLAY); + int sensitivity = getBackSensitivity(context, overlayManager); + setNavBarInteractionMode(overlayManager, BACK_GESTURE_INSET_OVERLAYS[sensitivity]); break; case KEY_SYSTEM_NAV_2BUTTONS: setNavBarInteractionMode(overlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY); @@ -206,10 +295,8 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { } } - /** - * Enables the specified overlay package. - */ - static void setNavBarInteractionMode(IOverlayManager overlayManager, String overlayPackage) { + private static void setNavBarInteractionMode(IOverlayManager overlayManager, + String overlayPackage) { try { overlayManager.setEnabledExclusiveInCategory(overlayPackage, USER_CURRENT); } catch (RemoteException e) { @@ -217,7 +304,7 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { } } - static void setIllustrationVideo(VideoPreference videoPref, String systemNavKey) { + private static void setIllustrationVideo(VideoPreference videoPref, String systemNavKey) { videoPref.setVideo(0, 0); switch (systemNavKey) { case KEY_SYSTEM_NAV_GESTURAL: @@ -233,41 +320,6 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment { } } - @Override - public void bindPreferenceExtra(RadioButtonPreference pref, - String key, CandidateInfo info, String defaultKey, String systemDefaultKey) { - if (!(info instanceof NavModeCandidateInfo) - || !(pref instanceof RadioButtonPreferenceWithExtraWidget)) { - return; - } - - pref.setSummary(((NavModeCandidateInfo) info).loadSummary()); - - RadioButtonPreferenceWithExtraWidget p = (RadioButtonPreferenceWithExtraWidget) pref; - if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL - && !SystemNavigationPreferenceController.isGestureNavSupportedByDefaultLauncher( - getContext())) { - p.setEnabled(false); - p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_INFO); - p.setExtraWidgetOnClickListener((v) -> { - showGestureNavDisabledDialog(); - }); - } else { - p.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_GONE); - } - } - - private void showGestureNavDisabledDialog() { - final String defaultHomeAppName = SystemNavigationPreferenceController - .getDefaultHomeAppName(getContext()); - final String message = getString(R.string.gesture_not_supported_dialog_message, - defaultHomeAppName); - AlertDialog d = new AlertDialog.Builder(getContext()) - .setMessage(message) - .setPositiveButton(R.string.okay, null) - .show(); - } - private boolean isAnyServiceSupportAccessibilityButton() { final AccessibilityManager ams = (AccessibilityManager) getContext().getSystemService( Context.ACCESSIBILITY_SERVICE); diff --git a/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java b/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java index 6a47ce516af..19fd92377c8 100644 --- a/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java +++ b/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidget.java @@ -27,6 +27,7 @@ import com.android.settings.R; public class RadioButtonPreferenceWithExtraWidget extends RadioButtonPreference { public static final int EXTRA_WIDGET_VISIBILITY_GONE = 0; public static final int EXTRA_WIDGET_VISIBILITY_INFO = 1; + public static final int EXTRA_WIDGET_VISIBILITY_SETTING = 2; private View mExtraWidgetDivider; private ImageView mExtraWidget; @@ -66,6 +67,15 @@ public class RadioButtonPreferenceWithExtraWidget extends RadioButtonPreference mExtraWidget.setClickable(true); mExtraWidget.setVisibility(View.VISIBLE); mExtraWidgetDivider.setVisibility(View.VISIBLE); + if (mExtraWidgetVisibility == EXTRA_WIDGET_VISIBILITY_INFO) { + mExtraWidget.setImageResource(R.drawable.ic_settings_about); + mExtraWidget.setContentDescription( + getContext().getResources().getText(R.string.information_label)); + } else if (mExtraWidgetVisibility == EXTRA_WIDGET_VISIBILITY_SETTING) { + mExtraWidget.setImageResource(R.drawable.ic_settings_accent); + mExtraWidget.setContentDescription( + getContext().getResources().getText(R.string.settings_label)); + } } } diff --git a/tests/robotests/src/com/android/settings/gestures/SystemNavigationGestureSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/SystemNavigationGestureSettingsTest.java index 1f3a758fd0f..24cb9ed3253 100644 --- a/tests/robotests/src/com/android/settings/gestures/SystemNavigationGestureSettingsTest.java +++ b/tests/robotests/src/com/android/settings/gestures/SystemNavigationGestureSettingsTest.java @@ -24,21 +24,30 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVE import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; +import static com.android.settings.gestures.SystemNavigationGestureSettings.BACK_GESTURE_INSET_DEFAULT_OVERLAY; +import static com.android.settings.gestures.SystemNavigationGestureSettings.BACK_GESTURE_INSET_OVERLAYS; import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_2BUTTONS; import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_3BUTTONS; import static com.android.settings.gestures.SystemNavigationGestureSettings.KEY_SYSTEM_NAV_GESTURAL; +import static com.android.settings.gestures.SystemNavigationGestureSettings.NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK; +import static com.android.settings.gestures.SystemNavigationGestureSettings.NAV_BAR_MODE_GESTURAL_OVERLAY_NARROW_BACK; +import static com.android.settings.gestures.SystemNavigationGestureSettings.NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; +import static junit.framework.Assert.assertEquals; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.content.Context; import android.content.om.IOverlayManager; -import android.os.ServiceManager; +import android.content.om.OverlayInfo; import android.provider.SearchIndexableResource; -import android.text.TextUtils; import com.android.internal.R; import com.android.settings.testutils.shadow.SettingsShadowResources; @@ -46,6 +55,8 @@ import com.android.settings.testutils.shadow.SettingsShadowResources; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @@ -57,17 +68,25 @@ import java.util.List; public class SystemNavigationGestureSettingsTest { private Context mContext; - - private IOverlayManager mOverlayManager; - private SystemNavigationGestureSettings mSettings; - @Before - public void setUp() { - mContext = RuntimeEnvironment.application; - mOverlayManager = mock(IOverlayManager.class); + @Mock + private IOverlayManager mOverlayManager; + @Mock + private OverlayInfo mOverlayInfoEnabled; + @Mock + private OverlayInfo mOverlayInfoDisabled; + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; mSettings = new SystemNavigationGestureSettings(); + + when(mOverlayInfoDisabled.isEnabled()).thenReturn(false); + when(mOverlayInfoEnabled.isEnabled()).thenReturn(true); + when(mOverlayManager.getOverlayInfo(any(), anyInt())).thenReturn(mOverlayInfoDisabled); } @Test @@ -82,34 +101,111 @@ public class SystemNavigationGestureSettingsTest { @Test public void testGetCurrentSystemNavigationMode() { - SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode, - NAV_BAR_MODE_GESTURAL); - assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext), - KEY_SYSTEM_NAV_GESTURAL)).isTrue(); + SettingsShadowResources.overrideResource( + R.integer.config_navBarInteractionMode, NAV_BAR_MODE_GESTURAL); + assertEquals(KEY_SYSTEM_NAV_GESTURAL, mSettings.getCurrentSystemNavigationMode(mContext)); - SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode, - NAV_BAR_MODE_3BUTTON); - assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext), - KEY_SYSTEM_NAV_3BUTTONS)).isTrue(); + SettingsShadowResources.overrideResource( + R.integer.config_navBarInteractionMode, NAV_BAR_MODE_3BUTTON); + assertEquals(KEY_SYSTEM_NAV_3BUTTONS, mSettings.getCurrentSystemNavigationMode(mContext)); - SettingsShadowResources.overrideResource(R.integer.config_navBarInteractionMode, - NAV_BAR_MODE_2BUTTON); - assertThat(TextUtils.equals(mSettings.getCurrentSystemNavigationMode(mContext), - KEY_SYSTEM_NAV_2BUTTONS)).isTrue(); + SettingsShadowResources.overrideResource( + R.integer.config_navBarInteractionMode, NAV_BAR_MODE_2BUTTON); + assertEquals(KEY_SYSTEM_NAV_2BUTTONS, mSettings.getCurrentSystemNavigationMode(mContext)); } @Test public void testSetCurrentSystemNavigationMode() throws Exception { - mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_GESTURAL); + mSettings.setBackSensitivity(mContext, mOverlayManager, 0); + mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager, + KEY_SYSTEM_NAV_GESTURAL); + verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( + NAV_BAR_MODE_GESTURAL_OVERLAY_NARROW_BACK, USER_CURRENT); + + mSettings.setBackSensitivity(mContext, mOverlayManager, 1); + mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager, + KEY_SYSTEM_NAV_GESTURAL); verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT); - mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_2BUTTONS); + mSettings.setBackSensitivity(mContext, mOverlayManager, 2); + mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager, + KEY_SYSTEM_NAV_GESTURAL); + verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( + NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK, USER_CURRENT); + + mSettings.setBackSensitivity(mContext, mOverlayManager, 3); + mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager, + KEY_SYSTEM_NAV_GESTURAL); + verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( + NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK, USER_CURRENT); + + mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager, + KEY_SYSTEM_NAV_2BUTTONS); verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( NAV_BAR_MODE_2BUTTON_OVERLAY, USER_CURRENT); - mSettings.setCurrentSystemNavigationMode(mOverlayManager, KEY_SYSTEM_NAV_3BUTTONS); + mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager, + KEY_SYSTEM_NAV_3BUTTONS); verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT); } + + @Test + public void testSetCurrentSystemNavigationMode_backSensitivityValuePersists() throws Exception { + SettingsShadowResources.overrideResource( + R.integer.config_navBarInteractionMode, NAV_BAR_MODE_3BUTTON); + + mSettings.setBackSensitivity(mContext, mOverlayManager, 2); + mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager, + KEY_SYSTEM_NAV_3BUTTONS); + verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( + NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT); + + // Return to Gesture navigation, without setting the sensitivity value. + mSettings.setCurrentSystemNavigationMode(mContext, mOverlayManager, + KEY_SYSTEM_NAV_GESTURAL); + verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( + NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK, USER_CURRENT); + } + + @Test + public void testGetBackSensitivity_default() { + assertEquals(BACK_GESTURE_INSET_DEFAULT_OVERLAY, + mSettings.getBackSensitivity(mContext, mOverlayManager)); + } + + @Test + public void testBackSensitivitySetterAndGetter_currentNavModeNotGestural() throws Exception { + SettingsShadowResources.overrideResource( + R.integer.config_navBarInteractionMode, NAV_BAR_MODE_3BUTTON); + + mSettings.setBackSensitivity(mContext, mOverlayManager, 3); + assertEquals(3, mSettings.getBackSensitivity(mContext, mOverlayManager)); + mSettings.setBackSensitivity(mContext, mOverlayManager, 2); + assertEquals(2, mSettings.getBackSensitivity(mContext, mOverlayManager)); + + verify(mOverlayManager, never()).setEnabledExclusiveInCategory(any(), anyInt()); + } + + @Test + public void testBackSensitivitySetterAndGetter_currentNavModeIsGestural() throws Exception { + SettingsShadowResources.overrideResource( + R.integer.config_navBarInteractionMode, NAV_BAR_MODE_GESTURAL); + + when(mOverlayManager.getOverlayInfo(BACK_GESTURE_INSET_OVERLAYS[3], USER_CURRENT)) + .thenReturn(mOverlayInfoEnabled); + mSettings.setBackSensitivity(mContext, mOverlayManager, 3); + assertEquals(3, mSettings.getBackSensitivity(mContext, mOverlayManager)); + + when(mOverlayManager.getOverlayInfo(BACK_GESTURE_INSET_OVERLAYS[2], USER_CURRENT)) + .thenReturn(mOverlayInfoEnabled); + mSettings.setBackSensitivity(mContext, mOverlayManager, 2); + assertEquals(2, mSettings.getBackSensitivity(mContext, mOverlayManager)); + + verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( + NAV_BAR_MODE_GESTURAL_OVERLAY_WIDE_BACK, USER_CURRENT); + verify(mOverlayManager, times(1)).setEnabledExclusiveInCategory( + NAV_BAR_MODE_GESTURAL_OVERLAY_EXTRA_WIDE_BACK, USER_CURRENT); + } } diff --git a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java index b84b3bb48d8..2e2d786787e 100644 --- a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java +++ b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceWithExtraWidgetTest.java @@ -18,6 +18,7 @@ package com.android.settings.widget; import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_GONE; import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_INFO; +import static com.android.settings.widget.RadioButtonPreferenceWithExtraWidget.EXTRA_WIDGET_VISIBILITY_SETTING; import static com.google.common.truth.Truth.assertThat; @@ -104,6 +105,18 @@ public class RadioButtonPreferenceWithExtraWidgetTest { assertEquals(View.VISIBLE, mExtraWidget.getVisibility()); assertEquals(View.VISIBLE, mExtraWidgetDivider.getVisibility()); assertThat(mExtraWidget.isClickable()).isTrue(); + assertEquals(mContext.getResources().getText(R.string.information_label), + mExtraWidget.getContentDescription()); + } + + @Test + public void testSetExtraWidgetVisibility_setting() { + mPreference.setExtraWidgetVisibility(EXTRA_WIDGET_VISIBILITY_SETTING); + assertEquals(View.VISIBLE, mExtraWidget.getVisibility()); + assertEquals(View.VISIBLE, mExtraWidgetDivider.getVisibility()); + assertThat(mExtraWidget.isClickable()).isTrue(); + assertEquals(mContext.getResources().getText(R.string.settings_label), + mExtraWidget.getContentDescription()); } @Test