diff --git a/res/raw/gesture_global_actions_panel.mp4 b/res/raw/gesture_global_actions_panel.mp4 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/res/values/strings.xml b/res/values/strings.xml index a31de98fb42..af94db3a358 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7264,6 +7264,8 @@ work challenge, work, profile work profile, managed profile, unify, unification, work, profile gestures + + global actions pay, tap, payments backup, back up gesture @@ -10148,6 +10150,15 @@ To check time, notifications, and other info, tap your screen. + + To show the global actions panel, press & hold Power button + + Show global actions + + Global actions + + The global actions panel can be accessed even when the device is locked. + Swipe fingerprint for notifications diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml index 8515bd71892..5dcb1b02d01 100644 --- a/res/xml/gestures.xml +++ b/res/xml/gestures.xml @@ -75,4 +75,10 @@ android:fragment="com.android.settings.gestures.PreventRingingGestureSettings" settings:controller="com.android.settings.gestures.PreventRingingParentPreferenceController" /> + + diff --git a/res/xml/global_actions_panel_settings.xml b/res/xml/global_actions_panel_settings.xml new file mode 100644 index 00000000000..af155bc74fc --- /dev/null +++ b/res/xml/global_actions_panel_settings.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/android/settings/gestures/GlobalActionsPanelPreferenceController.java b/src/com/android/settings/gestures/GlobalActionsPanelPreferenceController.java new file mode 100644 index 00000000000..07d303ba0ad --- /dev/null +++ b/src/com/android/settings/gestures/GlobalActionsPanelPreferenceController.java @@ -0,0 +1,69 @@ +/* + * 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.content.Context; +import android.provider.Settings; +import android.text.TextUtils; + +import com.android.internal.annotations.VisibleForTesting; + +public class GlobalActionsPanelPreferenceController extends GesturePreferenceController { + private static final String PREF_KEY_VIDEO = "global_actions_panel_video"; + + // TODO (b/132182180) -- Use Secure Settings constants instead of hard-coded strings + @VisibleForTesting + protected static final String ENABLED_SETTING = "global_actions_panel_enabled"; + // TODO (b/132182180) -- Use Secure Settings constants instead of hard-coded strings + @VisibleForTesting + protected static final String AVAILABLE_SETTING = "global_actions_panel_available"; + + @VisibleForTesting + protected static final String TOGGLE_KEY = "gesture_global_actions_panel_switch"; + + public GlobalActionsPanelPreferenceController(Context context, String key) { + super(context, key); + } + + @Override + public int getAvailabilityStatus() { + int enabled = Settings.Secure.getInt(mContext.getContentResolver(), AVAILABLE_SETTING, 0); + return enabled == 1 ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; + } + + @Override + public boolean setChecked(boolean isChecked) { + return Settings.Secure.putInt(mContext.getContentResolver(), ENABLED_SETTING, + isChecked ? 1 : 0); + } + + @Override + protected String getVideoPrefKey() { + return PREF_KEY_VIDEO; + } + + @Override + public boolean isSliceable() { + return TextUtils.equals(getPreferenceKey(), TOGGLE_KEY); + } + + @Override + public boolean isChecked() { + int enabled = Settings.Secure.getInt(mContext.getContentResolver(), ENABLED_SETTING, 0); + return enabled == 1; + } +} diff --git a/src/com/android/settings/gestures/GlobalActionsPanelSettings.java b/src/com/android/settings/gestures/GlobalActionsPanelSettings.java new file mode 100644 index 00000000000..0ace61f0c05 --- /dev/null +++ b/src/com/android/settings/gestures/GlobalActionsPanelSettings.java @@ -0,0 +1,62 @@ +/* + * 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.settings.SettingsEnums; +import android.content.Context; +import android.provider.SearchIndexableResource; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.search.SearchIndexable; + +import java.util.Arrays; +import java.util.List; + +@SearchIndexable +public class GlobalActionsPanelSettings extends DashboardFragment { + + private static final String TAG = "GlobalActionsPanelSettings"; + + // TODO (132184167): Use correct settings constant + @Override + public int getMetricsCategory() { + return SettingsEnums.SETTINGS_GESTURES; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.global_actions_panel_settings; + } + + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getXmlResourcesToIndex( + Context context, boolean enabled) { + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.global_actions_panel_settings; + return Arrays.asList(sir); + } + }; +} diff --git a/tests/robotests/src/com/android/settings/gestures/GlobalActionsPanelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/GlobalActionsPanelPreferenceControllerTest.java new file mode 100644 index 00000000000..1fed7df6059 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/GlobalActionsPanelPreferenceControllerTest.java @@ -0,0 +1,88 @@ +/* + * 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 static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.provider.Settings; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class GlobalActionsPanelPreferenceControllerTest { + + private Context mContext; + private GlobalActionsPanelPreferenceController mController; + + private static final String KEY_GESTURE_PANEL = "gesture_global_actions_panel"; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mController = new GlobalActionsPanelPreferenceController(mContext, KEY_GESTURE_PANEL); + } + + @Test + public void testIsChecked_panelEnabled() { + Settings.Secure.putInt( + mContext.getContentResolver(), mController.ENABLED_SETTING, 1); + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void testIsChecked_panelDisabled() { + Settings.Secure.putInt( + mContext.getContentResolver(), mController.ENABLED_SETTING, 0); + assertThat(mController.isChecked()).isFalse(); + } + + @Test + public void getAvailabilityStatus_panelAvailable() { + Settings.Secure.putInt( + mContext.getContentResolver(), mController.AVAILABLE_SETTING, 1); + assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_panelUnavailable() { + Settings.Secure.putInt( + mContext.getContentResolver(), mController.AVAILABLE_SETTING, 0); + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(mController.CONDITIONALLY_UNAVAILABLE); + } + + @Test + public void isSliceable_correctKey() { + final GlobalActionsPanelPreferenceController controller = + new GlobalActionsPanelPreferenceController(mContext, mController.TOGGLE_KEY); + assertThat(controller.isSliceable()).isTrue(); + } + + @Test + public void isSliceable_incorrectKey() { + final GlobalActionsPanelPreferenceController controller = + new GlobalActionsPanelPreferenceController(mContext, "bad_key"); + assertThat(controller.isSliceable()).isFalse(); + } +}