Add setting to allow configuration of long press home gesture
This allows configuration of long press home gesture on 2-/3-button navigation configurations. It allows the user to enable and disable the invocation of assistant app using said gesture. Bug: 191888710 Test: Unit tests and on a physical device. Change-Id: I18cb290058ac5c2a748d40802b942404f548b868
This commit is contained in:
@@ -3932,6 +3932,25 @@
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="Settings$ButtonNavigationSettingsActivity"
|
||||
android:label="Button Navigation Settings"
|
||||
android:exported="true"
|
||||
android:enabled="true">
|
||||
<intent-filter android:priority="32">
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="com.android.settings.SHORTCUT" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="com.android.settings.BUTTON_NAVIGATION_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.gestures.ButtonNavigationSettingsFragment" />
|
||||
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<activity android:name="Settings$MediaControlsSettingsActivity"
|
||||
android:exported="true"
|
||||
android:label="@strings/media_controls_title">
|
||||
|
@@ -11789,6 +11789,11 @@
|
||||
<!-- Summary text for swiping from bottom corners to invoke the digital assistant app. [CHAR LIMIT=NONE] -->
|
||||
<string name="assistant_corner_gesture_summary">Swipe up from a bottom corner to invoke digital assistant app.</string>
|
||||
|
||||
<!-- Title text for holding a long press on Home button to invoke the digital assistant app. [CHAR LIMIT=60] -->
|
||||
<string name="assistant_long_press_home_gesture_title">Hold Home to invoke assistant</string>
|
||||
<!-- Summary text for holding a long press on Home button to invoke the digital assistant app. [CHAR LIMIT=NONE] -->
|
||||
<string name="assistant_long_press_home_gesture_summary">Press and hold the Home button to invoke digital assistant app.</string>
|
||||
|
||||
<!-- Content description for the Information icon [CHAR LIMIT=30] -->
|
||||
<string name="information_label">Information</string>
|
||||
|
||||
@@ -11811,9 +11816,15 @@
|
||||
<!-- Title for the screen to show all the gesture navigation settings [CHAR LIMIT=80] -->
|
||||
<string name="gesture_settings_activity_title">Gesture Navigation Sensitivity</string>
|
||||
|
||||
<!-- Title for the screen to show all the 2- and 3-button navigation settings. [CHAR LIMIT=80] -->
|
||||
<string name="button_navigation_settings_activity_title">Button navigation</string>
|
||||
|
||||
<!-- Keywords for the gesture navigation settings. [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_gesture_navigation_settings">gesture navigation, back sensitivity, back gesture</string>
|
||||
|
||||
<!-- Keywords for the 2-/3-button navigation settings. [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_button_navigation_settings">navigation, home button</string>
|
||||
|
||||
<!-- Preference and settings suggestion title text for ambient display double tap (phone) [CHAR LIMIT=60]-->
|
||||
<string name="ambient_display_title" product="default">Double-tap to check phone</string>
|
||||
<!-- Preference and settings suggestion title text for ambient display double tap (tablet) [CHAR LIMIT=60]-->
|
||||
|
39
res/xml/button_navigation_settings.xml
Normal file
39
res/xml/button_navigation_settings.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="button_navigation_settings_page"
|
||||
android:title="@string/button_navigation_settings_activity_title"
|
||||
settings:keywords="@string/keywords_button_navigation_settings">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="assistant_button_navigation_category"
|
||||
android:persistent="false"
|
||||
android:title="@string/assistant_gesture_category_title">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="assistant_long_press_home_gesture"
|
||||
android:title="@string/assistant_long_press_home_gesture_title"
|
||||
android:summary="@string/assistant_long_press_home_gesture_summary"
|
||||
settings:controller="com.android.settings.gestures.ButtonNavigationSettingsAssistController"
|
||||
/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@@ -243,6 +243,8 @@ public class Settings extends SettingsActivity {
|
||||
public static class AutomaticStorageManagerSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class GamesStorageActivity extends SettingsActivity { /* empty */ }
|
||||
public static class GestureNavigationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
/** Activity to manage 2-/3-button navigation configuration. */
|
||||
public static class ButtonNavigationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class InteractAcrossProfilesSettingsActivity extends SettingsActivity {
|
||||
/* empty */
|
||||
}
|
||||
|
@@ -94,6 +94,7 @@ import com.android.settings.fuelgauge.PowerUsageSummary;
|
||||
import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleSettings;
|
||||
import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
|
||||
import com.android.settings.gestures.AssistGestureSettings;
|
||||
import com.android.settings.gestures.ButtonNavigationSettingsFragment;
|
||||
import com.android.settings.gestures.DoubleTapPowerSettings;
|
||||
import com.android.settings.gestures.DoubleTapScreenSettings;
|
||||
import com.android.settings.gestures.DoubleTwistGestureSettings;
|
||||
@@ -312,6 +313,7 @@ public class SettingsGateway {
|
||||
DarkModeSettingsFragment.class.getName(),
|
||||
BugReportHandlerPicker.class.getName(),
|
||||
GestureNavigationSettingsFragment.class.getName(),
|
||||
ButtonNavigationSettingsFragment.class.getName(),
|
||||
InteractAcrossProfilesSettings.class.getName(),
|
||||
InteractAcrossProfilesDetails.class.getName(),
|
||||
MediaControlsSettings.class.getName(),
|
||||
|
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
|
||||
/**
|
||||
* Configures behaviour of long press home button to invoke assistant app gesture.
|
||||
*/
|
||||
public class ButtonNavigationSettingsAssistController extends TogglePreferenceController {
|
||||
|
||||
public ButtonNavigationSettingsAssistController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
boolean onByDefault = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault);
|
||||
return Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, onByDefault ? 1 : 0) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
return Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, isChecked ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(mContext,
|
||||
NAV_BAR_MODE_2BUTTON_OVERLAY)
|
||||
|| SystemNavigationPreferenceController.isOverlayPackageAvailable(mContext,
|
||||
NAV_BAR_MODE_3BUTTON_OVERLAY)) {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
/**
|
||||
* A fragment that includes settings for 2- and 3-button navigation modes.
|
||||
*/
|
||||
@SearchIndexable(forTarget = SearchIndexable.MOBILE)
|
||||
public class ButtonNavigationSettingsFragment extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "ButtonNavigationSettingsFragment";
|
||||
|
||||
public static final String BUTTON_NAVIGATION_SETTINGS =
|
||||
"com.android.settings.BUTTON_NAVIGATION_SETTINGS";
|
||||
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.SETTINGS_BUTTON_NAV_DLG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.button_navigation_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.button_navigation_settings) {
|
||||
|
||||
@Override
|
||||
protected boolean isPageSearchEnabled(Context context) {
|
||||
return SystemNavigationPreferenceController.isOverlayPackageAvailable(context,
|
||||
NAV_BAR_MODE_2BUTTON_OVERLAY)
|
||||
|| SystemNavigationPreferenceController.isOverlayPackageAvailable(
|
||||
context,
|
||||
NAV_BAR_MODE_3BUTTON_OVERLAY);
|
||||
}
|
||||
};
|
||||
}
|
@@ -41,6 +41,7 @@ import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.accessibility.AccessibilityGestureNavigationTutorial;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
@@ -150,10 +151,19 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i
|
||||
|
||||
pref.setSummary(((CandidateInfoExtra) info).loadSummary());
|
||||
|
||||
if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL) {
|
||||
if (KEY_SYSTEM_NAV_GESTURAL.equals(info.getKey())) {
|
||||
pref.setExtraWidgetOnClickListener((v) -> startActivity(new Intent(
|
||||
GestureNavigationSettingsFragment.GESTURE_NAVIGATION_SETTINGS)));
|
||||
}
|
||||
|
||||
if (KEY_SYSTEM_NAV_2BUTTONS.equals(info.getKey()) || KEY_SYSTEM_NAV_3BUTTONS.equals(
|
||||
info.getKey())) {
|
||||
pref.setExtraWidgetOnClickListener((v) ->
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(ButtonNavigationSettingsFragment.class.getName())
|
||||
.setSourceMetricsCategory(SettingsEnums.SETTINGS_GESTURE_SWIPE_UP)
|
||||
.launch());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 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.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ButtonNavigationSettingsAssistControllerTest {
|
||||
|
||||
private static final String KEY_LONG_PRESS_HOME_FOR_ASSIST =
|
||||
"assistant_long_press_home_gesture";
|
||||
|
||||
private Context mContext;
|
||||
private Resources mResources;
|
||||
private ButtonNavigationSettingsAssistController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mResources = mock(Resources.class);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
|
||||
mController = new ButtonNavigationSettingsAssistController(
|
||||
mContext, KEY_LONG_PRESS_HOME_FOR_ASSIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_valueUnknownDefaultTrue_shouldReturnTrue() {
|
||||
when(mResources.getBoolean(
|
||||
com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault)).thenReturn(
|
||||
true);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_valueUnknownDefaultFalse_shouldReturnFalse() {
|
||||
when(mResources.getBoolean(
|
||||
com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault)).thenReturn(
|
||||
true);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_valueTrue_shouldReturnTrue() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, 1);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_valueFalse_shouldReturnFalse() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, 0);
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_valueFalse_shouldSetFalse() {
|
||||
mController.setChecked(false);
|
||||
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, -1)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_valueTrue_shouldSetTrue() {
|
||||
mController.setChecked(true);
|
||||
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, -1)).isEqualTo(1);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ButtonNavigationSettingsFragmentTest {
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_twoAndThreeButtonNavigationNotAvailable_allKeysNonIndexable() {
|
||||
assertThat(ButtonNavigationSettingsFragment.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
|
||||
ApplicationProvider.getApplicationContext())).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_twoButtonNavigationAvailable_allKeysIndexable() {
|
||||
addPackageToPackageManager(ApplicationProvider.getApplicationContext(),
|
||||
NAV_BAR_MODE_2BUTTON_OVERLAY);
|
||||
assertThat(ButtonNavigationSettingsFragment.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
|
||||
ApplicationProvider.getApplicationContext())).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_threeButtonNavigationAvailable_allKeysIndexable() {
|
||||
addPackageToPackageManager(ApplicationProvider.getApplicationContext(),
|
||||
NAV_BAR_MODE_3BUTTON_OVERLAY);
|
||||
assertThat(ButtonNavigationSettingsFragment.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
|
||||
ApplicationProvider.getApplicationContext())).isEmpty();
|
||||
}
|
||||
|
||||
private static void addPackageToPackageManager(Context context, String pkg) {
|
||||
ShadowPackageManager shadowPm = shadowOf(context.getPackageManager());
|
||||
PackageInfo pi = new PackageInfo();
|
||||
pi.packageName = pkg;
|
||||
shadowPm.installPackage(pi);
|
||||
}
|
||||
|
||||
}
|
@@ -152,9 +152,6 @@ public class LongPressPowerButtonPreferenceControllerTest {
|
||||
assertThat(Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.KEY_CHORD_POWER_VOLUME_UP, -1)).isEqualTo(
|
||||
LongPressPowerButtonPreferenceController.KEY_CHORD_POWER_VOLUME_UP_GLOBAL_ACTIONS);
|
||||
verify(mController.mAssistSwitch).setSummary(
|
||||
getString(
|
||||
R.string.power_menu_summary_long_press_for_assist_enabled));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user