Show a dialog with a slider to set the back gesture's sensitivity
am: 7d43125964
Change-Id: I8db63be340f8cf465599ad76ea52f8b2453de3c0
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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<? extends CandidateInfo> 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);
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user