diff --git a/res/drawable-night/double_tap_power_for_wallet.xml b/res/drawable-night/double_tap_power_for_wallet.xml new file mode 100644 index 00000000000..9c3de368258 --- /dev/null +++ b/res/drawable-night/double_tap_power_for_wallet.xml @@ -0,0 +1,36 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/double_tap_power_for_wallet.xml b/res/drawable/double_tap_power_for_wallet.xml new file mode 100644 index 00000000000..606c337a24d --- /dev/null +++ b/res/drawable/double_tap_power_for_wallet.xml @@ -0,0 +1,36 @@ + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 525de4796a0..ebd6d60ef55 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11158,6 +11158,23 @@ To quickly open camera, press the power button twice. Works from any screen. + + Double tap power button + + %1$s / %2$s + + Use double tap + + Double Tap Power Button + + Open Camera + + Access Camera + + Open Wallet + + Access Wallet + Flip camera for selfie diff --git a/res/xml/double_tap_power_settings.xml b/res/xml/double_tap_power_settings.xml index fb5dd52b913..783d045b5d5 100644 --- a/res/xml/double_tap_power_settings.xml +++ b/res/xml/double_tap_power_settings.xml @@ -1,6 +1,6 @@ + + + + + + + + diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml index 035c7f7c801..bfb359ae804 100644 --- a/res/xml/gestures.xml +++ b/res/xml/gestures.xml @@ -29,7 +29,7 @@ diff --git a/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceController.java new file mode 100644 index 00000000000..0c7c65a7ffa --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceController.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2024 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.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +public class DoubleTapPowerForCameraPreferenceController extends BasePreferenceController + implements LifecycleObserver, OnStart, OnStop { + + @Nullable private Preference mPreference; + private final ContentObserver mSettingsObserver = + new ContentObserver(new Handler(Looper.getMainLooper())) { + @Override + public void onChange(boolean selfChange, @Nullable Uri uri) { + if (mPreference == null || uri == null) { + return; + } + if (uri.equals( + DoubleTapPowerSettingsUtils + .DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED_URI)) { + mPreference.setEnabled( + DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled( + mContext)); + } else if (uri.equals( + DoubleTapPowerSettingsUtils + .DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION_URI)) { + updateState(mPreference); + } + } + }; + + public DoubleTapPowerForCameraPreferenceController( + @NonNull Context context, @NonNull String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + if (!DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext)) { + return UNSUPPORTED_ON_DEVICE; + } + return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext) + ? AVAILABLE + : DISABLED_DEPENDENT_SETTING; + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public void updateState(@NonNull Preference preference) { + super.updateState(preference); + if (preference instanceof SelectorWithWidgetPreference) { + ((SelectorWithWidgetPreference) preference) + .setChecked( + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)); + } + } + + @Override + public boolean handlePreferenceTreeClick(@NonNull Preference preference) { + if (!getPreferenceKey().equals(preference.getKey())) { + return false; + } + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForCameraLaunch(mContext); + if (preference instanceof SelectorWithWidgetPreference) { + ((SelectorWithWidgetPreference) preference).setChecked(true); + } + return true; + } + + @Override + public void onStart() { + DoubleTapPowerSettingsUtils.registerObserver(mContext, mSettingsObserver); + } + + @Override + public void onStop() { + DoubleTapPowerSettingsUtils.unregisterObserver(mContext, mSettingsObserver); + } +} diff --git a/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceController.java new file mode 100644 index 00000000000..56dda4d4953 --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceController.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2024 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.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +public class DoubleTapPowerForWalletPreferenceController extends BasePreferenceController + implements LifecycleObserver, OnStart, OnStop { + + @Nullable private Preference mPreference; + private final ContentObserver mSettingsObserver = + new ContentObserver(new Handler(Looper.getMainLooper())) { + @Override + public void onChange(boolean selfChange, @Nullable Uri uri) { + if (mPreference == null || uri == null) { + return; + } + if (uri.equals( + DoubleTapPowerSettingsUtils + .DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED_URI)) { + mPreference.setEnabled( + DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled( + mContext)); + } else if (uri.equals( + DoubleTapPowerSettingsUtils + .DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION_URI)) { + updateState(mPreference); + } + } + }; + + public DoubleTapPowerForWalletPreferenceController( + @NonNull Context context, @NonNull String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + if (!DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext)) { + return UNSUPPORTED_ON_DEVICE; + } + return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext) + ? AVAILABLE + : DISABLED_DEPENDENT_SETTING; + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public void updateState(@NonNull Preference preference) { + super.updateState(preference); + if (preference instanceof SelectorWithWidgetPreference) { + ((SelectorWithWidgetPreference) preference) + .setChecked( + !DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)); + } + } + + @Override + public boolean handlePreferenceTreeClick(@NonNull Preference preference) { + if (!getPreferenceKey().equals(preference.getKey())) { + return false; + } + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForWalletLaunch(mContext); + if (preference instanceof SelectorWithWidgetPreference) { + ((SelectorWithWidgetPreference) preference).setChecked(true); + } + return true; + } + + @Override + public void onStart() { + DoubleTapPowerSettingsUtils.registerObserver(mContext, mSettingsObserver); + } + + @Override + public void onStop() { + DoubleTapPowerSettingsUtils.unregisterObserver(mContext, mSettingsObserver); + } +} diff --git a/src/com/android/settings/gestures/DoubleTapPowerIllustrationPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerIllustrationPreferenceController.java new file mode 100644 index 00000000000..75af16845dc --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapPowerIllustrationPreferenceController.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 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.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION_URI; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.widget.IllustrationPreference; + +/** Configures the behaviour of the double tap power illustration. */ +public class DoubleTapPowerIllustrationPreferenceController extends BasePreferenceController + implements LifecycleObserver, OnStart, OnStop { + + @Nullable + private IllustrationPreference mIllustrationPreference; + private final ContentObserver mSettingsObserver = + new ContentObserver(new Handler(Looper.getMainLooper())) { + @Override + public void onChange(boolean selfChange, @Nullable Uri uri) { + if (mIllustrationPreference != null && uri != null) { + updateState(mIllustrationPreference); + } + } + }; + + public DoubleTapPowerIllustrationPreferenceController( + @NonNull Context context, @NonNull String key) { + super(context, key); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mIllustrationPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public void updateState(@NonNull Preference preference) { + super.updateState(preference); + + ((IllustrationPreference) preference) + .setLottieAnimationResId( + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled( + mContext) + ? R.drawable.quickly_open_camera + : R.drawable.double_tap_power_for_wallet); + } + + @Override + public void onStart() { + final ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver( + DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION_URI, true, mSettingsObserver); + } + + @Override + public void onStop() { + DoubleTapPowerSettingsUtils.unregisterObserver(mContext, mSettingsObserver); + } +} diff --git a/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceController.java new file mode 100644 index 00000000000..3eb18eb931d --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceController.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2024 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.android.settings.gestures.DoubleTapPowerSettingsUtils.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED_URI; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.settings.R; +import com.android.settings.widget.SettingsMainSwitchPreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; + +/** The controller to handle double tap power button main switch enable or disable state. */ +public class DoubleTapPowerMainSwitchPreferenceController + extends SettingsMainSwitchPreferenceController + implements LifecycleObserver, OnStart, OnStop { + + private final ContentObserver mSettingsObserver = + new ContentObserver(new Handler(Looper.getMainLooper())) { + @Override + public void onChange(boolean selfChange, @Nullable Uri uri) { + if (mSwitchPreference == null || uri == null) { + return; + } + updateState(mSwitchPreference); + } + }; + + public DoubleTapPowerMainSwitchPreferenceController( + @NonNull Context context, @NonNull String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext) + ? AVAILABLE + : UNSUPPORTED_ON_DEVICE; + } + + @Override + public boolean isChecked() { + return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext); + } + + @Override + public boolean setChecked(boolean isChecked) { + return DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled( + mContext, isChecked); + } + + @Override + public void onStart() { + final ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver( + DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED_URI, true, mSettingsObserver); + } + + @Override + public void onStop() { + DoubleTapPowerSettingsUtils.unregisterObserver(mContext, mSettingsObserver); + } + + @Override + public int getSliceHighlightMenuRes() { + return R.string.menu_key_system; + } +} diff --git a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java index 3d2e1768b2e..686d64cf1f5 100644 --- a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java +++ b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java @@ -21,22 +21,17 @@ import static android.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_D import android.content.Context; import android.content.SharedPreferences; import android.provider.Settings; -import android.text.TextUtils; -import androidx.annotation.VisibleForTesting; +import androidx.annotation.NonNull; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; -public class DoubleTapPowerPreferenceController extends GesturePreferenceController { +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; - @VisibleForTesting - static final int ON = 0; - @VisibleForTesting - static final int OFF = 1; +public class DoubleTapPowerPreferenceController extends BasePreferenceController { - private static final String PREF_KEY_VIDEO = "gesture_double_tap_power_video"; - - private final String SECURE_KEY = CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED; - - public DoubleTapPowerPreferenceController(Context context, String key) { + public DoubleTapPowerPreferenceController(@NonNull Context context, @NonNull String key) { super(context, key); } @@ -45,9 +40,13 @@ public class DoubleTapPowerPreferenceController extends GesturePreferenceControl || prefs.getBoolean(DoubleTapPowerSettings.PREF_KEY_SUGGESTION_COMPLETE, false); } - private static boolean isGestureAvailable(Context context) { - return context.getResources() - .getBoolean(com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled); + private static boolean isGestureAvailable(@NonNull Context context) { + if (!android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap()) { + return context.getResources() + .getBoolean( + com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled); + } + return DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(context); } @Override @@ -56,30 +55,41 @@ public class DoubleTapPowerPreferenceController extends GesturePreferenceControl } @Override - public boolean isSliceable() { - return TextUtils.equals(getPreferenceKey(), "gesture_double_tap_power"); + public void displayPreference(@NonNull PreferenceScreen screen) { + if (!android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap()) { + final Preference preference = screen.findPreference(getPreferenceKey()); + if (preference != null) { + preference.setTitle(R.string.double_tap_power_for_camera_title); + } + } + super.displayPreference(screen); } @Override - public boolean isPublicSlice() { - return true; - } - - @Override - protected String getVideoPrefKey() { - return PREF_KEY_VIDEO; - } - - @Override - public boolean isChecked() { - final int cameraDisabled = Settings.Secure.getInt(mContext.getContentResolver(), - SECURE_KEY, ON); - return cameraDisabled == ON; - } - - @Override - public boolean setChecked(boolean isChecked) { - return Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY, - isChecked ? ON : OFF); + @NonNull + public CharSequence getSummary() { + if (!android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap()) { + final boolean isCameraDoubleTapPowerGestureEnabled = + Settings.Secure.getInt( + mContext.getContentResolver(), + CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, + DoubleTapPowerToOpenCameraPreferenceController.ON) + == DoubleTapPowerToOpenCameraPreferenceController.ON; + return mContext.getText( + isCameraDoubleTapPowerGestureEnabled + ? R.string.gesture_setting_on + : R.string.gesture_setting_off); + } + if (DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext)) { + final CharSequence onString = + mContext.getText(com.android.settings.R.string.gesture_setting_on); + final CharSequence actionString = + DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureForCameraLaunchEnabled( + mContext) + ? mContext.getText(R.string.double_tap_power_camera_action_summary) + : mContext.getText(R.string.double_tap_power_wallet_action_summary); + return mContext.getString(R.string.double_tap_power_summary, onString, actionString); + } + return mContext.getText(com.android.settings.R.string.gesture_setting_off); } } diff --git a/src/com/android/settings/gestures/DoubleTapPowerSettings.java b/src/com/android/settings/gestures/DoubleTapPowerSettings.java index 577758df396..076f23fa660 100644 --- a/src/com/android/settings/gestures/DoubleTapPowerSettings.java +++ b/src/com/android/settings/gestures/DoubleTapPowerSettings.java @@ -19,6 +19,9 @@ package com.android.settings.gestures; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.SharedPreferences; +import android.provider.SearchIndexableResource; + +import androidx.annotation.NonNull; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; @@ -27,6 +30,8 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.search.SearchIndexable; +import java.util.List; + @SearchIndexable public class DoubleTapPowerSettings extends DashboardFragment { @@ -56,9 +61,24 @@ public class DoubleTapPowerSettings extends DashboardFragment { @Override protected int getPreferenceScreenResId() { - return R.xml.double_tap_power_settings; + return android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap() + ? R.xml.double_tap_power_settings + : R.xml.double_tap_power_to_open_camera_settings; } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.double_tap_power_settings); + new BaseSearchIndexProvider() { + @Override + @NonNull + public List getXmlResourcesToIndex( + @NonNull Context context, boolean enabled) { + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = + android.service.quickaccesswallet.Flags + .launchWalletOptionOnPowerDoubleTap() + ? R.xml.double_tap_power_settings + : R.xml.double_tap_power_to_open_camera_settings; + return List.of(sir); + } + }; } diff --git a/src/com/android/settings/gestures/DoubleTapPowerSettingsUtils.java b/src/com/android/settings/gestures/DoubleTapPowerSettingsUtils.java new file mode 100644 index 00000000000..a1bf9cbd48c --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapPowerSettingsUtils.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2016 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.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.provider.Settings; + +import androidx.annotation.NonNull; + +import com.android.internal.R; + +/** Common code for double tap power settings shared between controllers. */ +final class DoubleTapPowerSettingsUtils { + + /** Setting storing whether the double tap power button gesture is enabled. */ + private static final String DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED = + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED; + + static final Uri DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED_URI = + Settings.Secure.getUriFor(DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED); + + /** Setting storing the target action of the double tap power button gesture. */ + private static final String DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION = + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE; + + static final Uri DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION_URI = + Settings.Secure.getUriFor(DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION); + + private static final int DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE = 0; + private static final int DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE = 1; + + static final int ON = 1; + static final int OFF = 0; + + /** + * @return true if double tap power button gesture is available. + */ + public static boolean isDoubleTapPowerButtonGestureAvailable(@NonNull Context context) { + return context.getResources().getBoolean(R.bool.config_doubleTapPowerGestureEnabled); + } + + /** + * Gets double tap power button gesture enable or disable flag from Settings provider. + * + * @return true if double tap on the power button gesture is currently enabled. + * @param context App context + */ + public static boolean isDoubleTapPowerButtonGestureEnabled(@NonNull Context context) { + return Settings.Secure.getInt( + context.getContentResolver(), DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, ON) + == ON; + } + + /** + * Sets double tap power button gesture enable or disable flag to Settings provider. + * + * @param context App context + * @param enable enable or disable double tap power button gesture. + * @return {@code true} if the setting is updated. + */ + public static boolean setDoubleTapPowerButtonGestureEnabled( + @NonNull Context context, boolean enable) { + return Settings.Secure.putInt( + context.getContentResolver(), + DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, + enable ? ON : OFF); + } + + /** + * @return true if double tap on the power button gesture for camera launch is currently + * enabled. + * @param context App context + */ + public static boolean isDoubleTapPowerButtonGestureForCameraLaunchEnabled( + @NonNull Context context) { + return Settings.Secure.getInt( + context.getContentResolver(), + DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION, + context.getResources() + .getInteger( + com.android.internal.R.integer + .config_defaultDoubleTapPowerGestureAction)) + == DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE; + } + + /** + * Sets double tap power button gesture behavior to launch the camera. + * + * @param context App context + * @return {@code true} if the setting is updated. + */ + public static boolean setDoubleTapPowerButtonForCameraLaunch(@NonNull Context context) { + return Settings.Secure.putInt( + context.getContentResolver(), + DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION, + DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE); + } + + /** + * Sets double tap power button gesture behavior to launch the wallet. + * + * @param context App context + * @return {@code true} if the setting is updated. + */ + public static boolean setDoubleTapPowerButtonForWalletLaunch(@NonNull Context context) { + return Settings.Secure.putInt( + context.getContentResolver(), + DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION, + DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE); + } + + /** + * Registers observer for settings state. + * + * @param observer Settings Content Observer + */ + public static void registerObserver( + @NonNull Context context, @NonNull ContentObserver observer) { + final ContentResolver resolver = context.getContentResolver(); + resolver.registerContentObserver( + DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED_URI, true, observer); + resolver.registerContentObserver( + DOUBLE_TAP_POWER_BUTTON_GESTURE_TARGET_ACTION_URI, true, observer); + } + + /** Unregisters observer. */ + public static void unregisterObserver( + @NonNull Context context, @NonNull ContentObserver observer) { + final ContentResolver resolver = context.getContentResolver(); + resolver.unregisterContentObserver(observer); + } +} diff --git a/src/com/android/settings/gestures/DoubleTapPowerToOpenCameraPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerToOpenCameraPreferenceController.java new file mode 100644 index 00000000000..4362a661007 --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapPowerToOpenCameraPreferenceController.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2024 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.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED; + +import android.content.Context; +import android.provider.Settings; +import android.text.TextUtils; + +import androidx.annotation.NonNull; + +import com.android.settings.R; +import com.android.settings.core.TogglePreferenceController; + +public class DoubleTapPowerToOpenCameraPreferenceController extends TogglePreferenceController { + + static final int ON = 0; + static final int OFF = 1; + + public DoubleTapPowerToOpenCameraPreferenceController( + @NonNull Context context, @NonNull String key) { + super(context, key); + } + + @Override + public int getAvailabilityStatus() { + return mContext.getResources() + .getBoolean( + com.android.internal.R.bool + .config_cameraDoubleTapPowerGestureEnabled) + ? AVAILABLE + : UNSUPPORTED_ON_DEVICE; + } + + @Override + public boolean isChecked() { + return Settings.Secure.getInt( + mContext.getContentResolver(), CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, ON) + == ON; + } + + @Override + public boolean setChecked(boolean isChecked) { + return Settings.Secure.putInt( + mContext.getContentResolver(), + CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, + isChecked ? ON : OFF); + } + + @Override + public boolean isSliceable() { + return TextUtils.equals(getPreferenceKey(), "gesture_double_tap_power"); + } + + @Override + public boolean isPublicSlice() { + return true; + } + + @Override + public int getSliceHighlightMenuRes() { + return R.string.menu_key_system; + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceControllerTest.java new file mode 100644 index 00000000000..cc710ec29e6 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForCameraPreferenceControllerTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2024 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 androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.internal.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class DoubleTapPowerForCameraPreferenceControllerTest { + + private static final String KEY = "gesture_double_power_tap_launch_camera"; + private Context mContext; + private Resources mResources; + private DoubleTapPowerForCameraPreferenceController mController; + private SelectorWithWidgetPreference mPreference; + + @Before + public void setUp() { + mContext = spy(ApplicationProvider.getApplicationContext()); + mResources = mock(Resources.class); + when(mContext.getResources()).thenReturn(mResources); + mController = new DoubleTapPowerForCameraPreferenceController(mContext, KEY); + mPreference = new SelectorWithWidgetPreference(mContext); + } + + @Test + public void updateState_launchCameraEnabled_preferenceChecked() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForCameraLaunch(mContext); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void updateState_launchCameraDisabled_preferenceNotChecked() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForWalletLaunch(mContext); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerGestureNotAvailable_preferenceUnsupported() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(false); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerButtonDisabled_preferenceDisabled() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, false); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerCameraLaunchEnabled_preferenceEnabled() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, true); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceControllerTest.java new file mode 100644 index 00000000000..c86a82edd0d --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerForWalletPreferenceControllerTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2024 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 androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.internal.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class DoubleTapPowerForWalletPreferenceControllerTest { + + private static final String KEY = "gesture_double_power_tap_launch_wallet"; + private Context mContext; + private Resources mResources; + private DoubleTapPowerForWalletPreferenceController mController; + private SelectorWithWidgetPreference mPreference; + + @Before + public void setUp() { + mContext = spy(ApplicationProvider.getApplicationContext()); + mResources = mock(Resources.class); + when(mContext.getResources()).thenReturn(mResources); + mController = new DoubleTapPowerForWalletPreferenceController(mContext, KEY); + mPreference = new SelectorWithWidgetPreference(mContext); + } + + @Test + public void updateState_launchWalletEnabled_preferenceChecked() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForWalletLaunch(mContext); + + mController.updateState(mPreference); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void updateState_launchWalletDisabled_preferenceNotChecked() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForCameraLaunch(mContext); + + mController.updateState(mPreference); + + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerGestureNotAvailable_preferenceUnsupported() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(false); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerButtonDisabled_preferenceDisabled() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, false); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerWalletLaunchEnabled_preferenceEnabled() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, true); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerIllustrationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerIllustrationPreferenceControllerTest.java new file mode 100644 index 00000000000..1ea2a4ed8bb --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerIllustrationPreferenceControllerTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 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.when; + +import android.app.Application; + +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.settings.R; +import com.android.settingslib.widget.IllustrationPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class DoubleTapPowerIllustrationPreferenceControllerTest { + + private static final String KEY = "gesture_double_tap_power_video"; + private Application mContext; + private IllustrationPreference mPreference; + private DoubleTapPowerIllustrationPreferenceController mController; + + @Before + public void setUp() { + mContext = ApplicationProvider.getApplicationContext(); + mPreference = new IllustrationPreference(mContext); + mController = new DoubleTapPowerIllustrationPreferenceController(mContext, KEY); + + PreferenceScreen mScreen = mock(PreferenceScreen.class); + when(mScreen.findPreference(KEY)).thenReturn(mPreference); + mController.displayPreference(mScreen); + } + + @Test + public void updateState_setDoubleTapPowerForCamera_showsCameraIllustration() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForCameraLaunch(mContext); + + mController.updateState(mPreference); + + assertThat(mPreference.getLottieAnimationResId()).isEqualTo(R.drawable.quickly_open_camera); + } + + @Test + public void updateState_setDoubleTapPowerForWallet_showsWalletIllustration() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForWalletLaunch(mContext); + + mController.updateState(mPreference); + + assertThat(mPreference.getLottieAnimationResId()) + .isEqualTo(R.drawable.double_tap_power_for_wallet); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceControllerTest.java new file mode 100644 index 00000000000..502e52ec6c3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerMainSwitchPreferenceControllerTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2024 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 androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.internal.R; +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class DoubleTapPowerMainSwitchPreferenceControllerTest { + + private static final String KEY = "gesture_double_tap_power_enabled_main_switch"; + + private Context mContext; + private Resources mResources; + private DoubleTapPowerMainSwitchPreferenceController mController; + + @Before + public void setUp() { + mContext = spy(ApplicationProvider.getApplicationContext()); + mResources = mock(Resources.class); + when(mContext.getResources()).thenReturn(mResources); + mController = new DoubleTapPowerMainSwitchPreferenceController(mContext, KEY); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerGestureAvailable_preferenceEnabled() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerGestureUnavailable_preferenceUnsupported() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(false); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + public void isChecked_setDoubleTapPowerGestureEnabled_mainSwitchChecked() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, true); + + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void isChecked_setDoubleTapPowerGestureDisabled_mainSwitchUnchecked() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, false); + + assertThat(mController.isChecked()).isFalse(); + } + + @Test + public void setChecked_checkMainSwitch_doubleTapPowerGestureEnabled() { + mController.setChecked(true); + assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext)) + .isTrue(); + } + + @Test + public void setChecked_uncheckMainSwitch_doubleTapPowerGestureDisabled() { + mController.setChecked(false); + assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext)) + .isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java index 72dd36e60a0..17b03f355bf 100644 --- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java @@ -17,23 +17,37 @@ package com.android.settings.gestures; import static android.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED; +import static android.provider.Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED; -import static com.android.settings.gestures.DoubleTapPowerPreferenceController.OFF; -import static com.android.settings.gestures.DoubleTapPowerPreferenceController.ON; import static com.android.settings.gestures.DoubleTapPowerPreferenceController.isSuggestionComplete; +import static com.android.settings.gestures.DoubleTapPowerToOpenCameraPreferenceController.OFF; +import static com.android.settings.gestures.DoubleTapPowerToOpenCameraPreferenceController.ON; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; +import android.service.quickaccesswallet.Flags; +import android.text.TextUtils; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl; import com.android.settings.testutils.shadow.SettingsShadowResources; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -44,16 +58,22 @@ import org.robolectric.annotation.Config; @Config(shadows = SettingsShadowResources.class) public class DoubleTapPowerPreferenceControllerTest { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private Context mContext; private ContentResolver mContentResolver; private DoubleTapPowerPreferenceController mController; + private Preference mPreference; + private PreferenceScreen mScreen; private static final String KEY_DOUBLE_TAP_POWER = "gesture_double_tap_power"; @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = RuntimeEnvironment.getApplication(); mContentResolver = mContext.getContentResolver(); mController = new DoubleTapPowerPreferenceController(mContext, KEY_DOUBLE_TAP_POWER); + mPreference = new Preference(mContext); + mScreen = mock(PreferenceScreen.class); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); } @After @@ -62,7 +82,26 @@ public class DoubleTapPowerPreferenceControllerTest { } @Test - public void isAvailable_configIsTrue_shouldReturnTrue() { + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isAvailable_flagEnabled_configIsTrue_returnsTrue() { + SettingsShadowResources.overrideResource( + com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, Boolean.TRUE); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isAvailable_flagEnabled_configIsFalse_returnsFalse() { + SettingsShadowResources.overrideResource( + com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, Boolean.FALSE); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isAvailable_flagDisabled_configIsTrue_returnsTrue() { SettingsShadowResources.overrideResource( com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled, Boolean.TRUE); @@ -71,7 +110,8 @@ public class DoubleTapPowerPreferenceControllerTest { } @Test - public void isAvailable_configIsTrue_shouldReturnFalse() { + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isAvailable_flagDisabled_configIsFalse_returnsFalse() { SettingsShadowResources.overrideResource( com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled, Boolean.FALSE); @@ -80,43 +120,63 @@ public class DoubleTapPowerPreferenceControllerTest { } @Test - public void testIsChecked_configIsNotSet_shouldReturnTrue() { - // Set the setting to be enabled. - Settings.Secure.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, ON); - mController = new DoubleTapPowerPreferenceController(mContext, KEY_DOUBLE_TAP_POWER); + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isSuggestionCompleted_enableFlag_doubleTapPower_trueWhenNotAvailable() { + SettingsShadowResources.overrideResource( + com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, false); - assertThat(mController.isChecked()).isTrue(); + assertThat(isSuggestionComplete(mContext, null /* prefs */)).isTrue(); } @Test - public void testIsChecked_configIsSet_shouldReturnFalse() { - // Set the setting to be disabled. - Settings.Secure.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, OFF); - mController = new DoubleTapPowerPreferenceController(mContext, KEY_DOUBLE_TAP_POWER); + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isSuggestionCompleted_enableFlag_doubleTapPower_falseWhenNotVisited() { + SettingsShadowResources.overrideResource( + com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, true); + // No stored value in shared preferences if not visited yet. + final SharedPreferences prefs = + new SuggestionFeatureProviderImpl().getSharedPrefs(mContext); - assertThat(mController.isChecked()).isFalse(); + assertThat(isSuggestionComplete(mContext, prefs)).isFalse(); } @Test - public void isSuggestionCompleted_doubleTapPower_trueWhenNotAvailable() { + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isSuggestionCompleted_enableFlag_doubleTapPower_trueWhenVisited() { + SettingsShadowResources.overrideResource( + com.android.internal.R.bool.config_doubleTapPowerGestureEnabled, true); + // No stored value in shared preferences if not visited yet. + final SharedPreferences prefs = + new SuggestionFeatureProviderImpl().getSharedPrefs(mContext); + prefs.edit().putBoolean(DoubleTapPowerSettings.PREF_KEY_SUGGESTION_COMPLETE, true).commit(); + + assertThat(isSuggestionComplete(mContext, prefs)).isTrue(); + } + + @Test + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isSuggestionCompleted_disableFlag_doubleTapPower_trueWhenNotAvailable() { SettingsShadowResources.overrideResource( com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled, false); - assertThat(isSuggestionComplete(mContext, null/* prefs */)).isTrue(); + assertThat(isSuggestionComplete(mContext, null /* prefs */)).isTrue(); } @Test - public void isSuggestionCompleted_doubleTapPower_falseWhenNotVisited() { + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isSuggestionCompleted_disableFlag_doubleTapPower_falseWhenNotVisited() { SettingsShadowResources.overrideResource( com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled, true); // No stored value in shared preferences if not visited yet. final SharedPreferences prefs = new SuggestionFeatureProviderImpl().getSharedPrefs(mContext); + assertThat(isSuggestionComplete(mContext, prefs)).isFalse(); } @Test - public void isSuggestionCompleted_doubleTapPower_trueWhenVisited() { + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void isSuggestionCompleted_disableFlag_doubleTapPower_trueWhenVisited() { SettingsShadowResources.overrideResource( com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled, true); // No stored value in shared preferences if not visited yet. @@ -128,21 +188,92 @@ public class DoubleTapPowerPreferenceControllerTest { } @Test - public void isSliceableCorrectKey_returnsTrue() { - final DoubleTapPowerPreferenceController controller = - new DoubleTapPowerPreferenceController(mContext, "gesture_double_tap_power"); - assertThat(controller.isSliceable()).isTrue(); + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void displayPreference_flagDisabled_doubleTapPowerLegacyTitleIsDisplayed() { + mController.displayPreference(mScreen); + + assertThat( + TextUtils.equals( + mPreference.getTitle(), + mContext.getText(R.string.double_tap_power_for_camera_title))) + .isTrue(); } @Test - public void isSliceableIncorrectKey_returnsFalse() { - final DoubleTapPowerPreferenceController controller = - new DoubleTapPowerPreferenceController(mContext, "bad_key"); - assertThat(controller.isSliceable()).isFalse(); + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void getSummary_flagDisabled_doubleTapPowerEnabled_returnsOn() { + // Set the setting to be enabled. + Settings.Secure.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, ON); + + assertThat( + TextUtils.equals( + mController.getSummary(), + mContext.getText(R.string.gesture_setting_on))) + .isTrue(); } @Test - public void isPublicSlice_returnTrue() { - assertThat(mController.isPublicSlice()).isTrue(); + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void getSummary_flagDisabled_doubleTapPowerDisabled_returnsOff() { + // Set the setting to be disabled. + Settings.Secure.putInt(mContentResolver, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, OFF); + + assertThat( + TextUtils.equals( + mController.getSummary(), + mContext.getText(R.string.gesture_setting_off))) + .isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void getSummary_flagEnabled_doubleTapPowerDisabled_returnsOff() { + // Set the setting to be disabled. + Settings.Secure.putInt( + mContentResolver, DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, 0 /* OFF */); + + assertThat( + TextUtils.equals( + mController.getSummary(), + mContext.getText(R.string.gesture_setting_off))) + .isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void getSummary_flagEnabled_doubleTapPowerEnabled_cameraTargetAction_returnsSummary() { + // Set the setting to be enabled. + Settings.Secure.putInt( + mContentResolver, DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, 1 /* ON */); + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForCameraLaunch(mContext); + + assertThat( + TextUtils.equals( + mController.getSummary(), + mContext.getString( + R.string.double_tap_power_summary, + mContext.getText(R.string.gesture_setting_on), + mContext.getText( + R.string.double_tap_power_camera_action_summary)))) + .isTrue(); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void getSummary_flagEnabled_doubleTapPowerEnabled_walletTargetAction_returnsSummary() { + // Set the setting to be enabled. + Settings.Secure.putInt( + mContentResolver, DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, 1 /* ON */); + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForWalletLaunch(mContext); + + assertThat( + TextUtils.equals( + mController.getSummary(), + mContext.getString( + R.string.double_tap_power_summary, + mContext.getText(R.string.gesture_setting_on), + mContext.getText( + R.string.double_tap_power_wallet_action_summary)))) + .isTrue(); } } diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsTest.java index a08b81800a4..7d4f52e67a2 100644 --- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsTest.java +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsTest.java @@ -18,9 +18,16 @@ package com.android.settings.gestures; import static com.google.common.truth.Truth.assertThat; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.SearchIndexableResource; +import android.service.quickaccesswallet.Flags; + +import com.android.settings.R; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -31,6 +38,7 @@ import java.util.List; @RunWith(RobolectricTestRunner.class) public class DoubleTapPowerSettingsTest { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private DoubleTapPowerSettings mSettings; @Before @@ -39,12 +47,38 @@ public class DoubleTapPowerSettingsTest { } @Test - public void testSearchIndexProvider_shouldIndexResource() { + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void getPreferenceScreenResId_flagEnabled_returnsFlagEnabledResId() { + assertThat(mSettings.getPreferenceScreenResId()).isEqualTo(R.xml.double_tap_power_settings); + } + + @Test + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void getPreferenceScreenResId_flagDisabled_returnsFlagDisabledResId() { + assertThat(mSettings.getPreferenceScreenResId()) + .isEqualTo(R.xml.double_tap_power_to_open_camera_settings); + } + + @Test + @EnableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void testSearchIndexProvider_flagEnabled_shouldIndexFlagEnabledResource() { final List indexRes = - DoubleTapPowerSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( - RuntimeEnvironment.application, true /* enabled */); + DoubleTapPowerSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( + RuntimeEnvironment.getApplication(), true /* enabled */); assertThat(indexRes).isNotNull(); - assertThat(indexRes.get(0).xmlResId).isEqualTo(mSettings.getPreferenceScreenResId()); + assertThat(indexRes.get(0).xmlResId).isEqualTo(R.xml.double_tap_power_settings); + } + + @Test + @DisableFlags(Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void testSearchIndexProvider_flagDisabled_shouldIndexFlagDisabledResource() { + final List indexRes = + DoubleTapPowerSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( + RuntimeEnvironment.getApplication(), true /* enabled */); + + assertThat(indexRes).isNotNull(); + assertThat(indexRes.get(0).xmlResId) + .isEqualTo(R.xml.double_tap_power_to_open_camera_settings); } } diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsUtilsTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsUtilsTest.java new file mode 100644 index 00000000000..817f198a5b2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerSettingsUtilsTest.java @@ -0,0 +1,203 @@ +/* + * 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.android.settings.gestures.DoubleTapPowerSettingsUtils.OFF; +import static com.android.settings.gestures.DoubleTapPowerSettingsUtils.ON; + +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 androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.internal.R; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class DoubleTapPowerSettingsUtilsTest { + + private static final int DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE = 0; + private static final int DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE = 1; + + private Context mContext; + private Resources mResources; + + @Before + public void setUp() { + mContext = spy(ApplicationProvider.getApplicationContext()); + mResources = mock(Resources.class); + when(mContext.getResources()).thenReturn(mResources); + } + + @Test + public void isDoubleTapPowerButtonGestureAvailable_setAvailable_returnsTrue() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(true); + + assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext)) + .isTrue(); + } + + @Test + public void isDoubleTapPowerButtonGestureAvailable_setUnavailable_returnsFalse() { + when(mResources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled)).thenReturn(false); + + assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureAvailable(mContext)) + .isFalse(); + } + + @Test + public void isDoubleTapPowerButtonGestureEnabled_setEnabled_returnsTrue() { + Settings.Secure.putInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, + ON); + + assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext)) + .isTrue(); + } + + @Test + public void isDoubleTapPowerButtonGestureEnabled_setDisabled_returnsFalse() { + Settings.Secure.putInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, + OFF); + + assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext)) + .isFalse(); + } + + @Test + public void isDoubleTapPowerButtonGestureEnabled_valueNotSet_returnsTrue() { + assertThat(DoubleTapPowerSettingsUtils.isDoubleTapPowerButtonGestureEnabled(mContext)) + .isTrue(); + } + + @Test + public void setDoubleTapPowerButtonGestureEnabled_setEnabled_returnsEnabled() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, true); + + assertThat( + Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, + OFF)) + .isEqualTo(ON); + } + + @Test + public void setDoubleTapPowerButtonGestureEnabled_setDisabled_returnsDisabled() { + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonGestureEnabled(mContext, false); + + assertThat( + Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, + ON)) + .isEqualTo(OFF); + } + + @Test + public void isDoubleTapPowerButtonGestureForCameraLaunchEnabled_valueSetToCamera_returnsTrue() { + Settings.Secure.putInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, + DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE); + + assertThat( + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) + .isTrue(); + } + + @Test + public void + isDoubleTapPowerButtonGestureForCameraLaunchEnabled_valueNotSetToCamera_returnsFalse() { + Settings.Secure.putInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, + DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE); + + assertThat( + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) + .isFalse(); + } + + @Test + public void + isDoubleTapPowerButtonGestureForCameraLaunchEnabled_defaultSetToCamera_returnsTrue() { + when(mResources.getInteger(R.integer.config_defaultDoubleTapPowerGestureAction)) + .thenReturn(DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE); + + assertThat( + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) + .isTrue(); + } + + @Test + public void + isDoubleTapPowerButtonGestureForCameraLaunchEnabled_defaultNotCamera_returnsFalse() { + when(mResources.getInteger(R.integer.config_defaultDoubleTapPowerGestureAction)) + .thenReturn(DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE); + + assertThat( + DoubleTapPowerSettingsUtils + .isDoubleTapPowerButtonGestureForCameraLaunchEnabled(mContext)) + .isFalse(); + } + + @Test + public void setDoubleTapPowerButtonForCameraLaunch_setGestureBehaviorToCameraLaunch() { + boolean result = + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForCameraLaunch(mContext); + + assertThat(result).isTrue(); + assertThat( + Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, + DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE)) + .isEqualTo(DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE); + } + + @Test + public void setDoubleTapPowerButtonForWalletLaunch_setGestureBehaviorToWalletLaunch() { + boolean result = + DoubleTapPowerSettingsUtils.setDoubleTapPowerButtonForWalletLaunch(mContext); + + assertThat(result).isTrue(); + assertThat( + Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, + DOUBLE_TAP_POWER_BUTTON_CAMERA_LAUNCH_VALUE)) + .isEqualTo(DOUBLE_TAP_POWER_BUTTON_WALLET_LAUNCH_VALUE); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerToOpenCameraPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerToOpenCameraPreferenceControllerTest.java new file mode 100644 index 00000000000..54d17ba258c --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerToOpenCameraPreferenceControllerTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2024 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.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED; + +import static com.android.settings.gestures.DoubleTapPowerToOpenCameraPreferenceController.OFF; +import static com.android.settings.gestures.DoubleTapPowerToOpenCameraPreferenceController.ON; + +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.platform.test.flag.junit.SetFlagsRule; +import android.provider.Settings; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.internal.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.testutils.shadow.SettingsShadowResources; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(AndroidJUnit4.class) +@Config(shadows = SettingsShadowResources.class) +public class DoubleTapPowerToOpenCameraPreferenceControllerTest { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private Context mContext; + private Resources mResources; + private DoubleTapPowerToOpenCameraPreferenceController mController; + private static final String KEY_DOUBLE_TAP_POWER = "gesture_double_tap_power"; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.getApplication()); + mResources = mock(Resources.class); + when(mContext.getResources()).thenReturn(mResources); + mController = + new DoubleTapPowerToOpenCameraPreferenceController(mContext, KEY_DOUBLE_TAP_POWER); + } + + @After + public void tearDown() { + SettingsShadowResources.reset(); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerGestureDisabled_preferenceUnsupported() { + when(mResources.getBoolean(R.bool.config_cameraDoubleTapPowerGestureEnabled)) + .thenReturn(false); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + public void getAvailabilityStatus_setDoubleTapPowerGestureEnabled_preferenceSupported() { + when(mResources.getBoolean(R.bool.config_cameraDoubleTapPowerGestureEnabled)) + .thenReturn(true); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + public void isChecked_configIsNotSet_returnsTrue() { + // Set the setting to be enabled. + Settings.Secure.putInt( + mContext.getContentResolver(), CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, ON); + + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void isChecked_setConfigFalse_returnsFalse() { + // Set the setting to be disabled. + Settings.Secure.putInt( + mContext.getContentResolver(), CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, OFF); + + assertThat(mController.isChecked()).isFalse(); + } + + @Test + public void isChecked_setConfigTrue_returnsFalse() { + // Set the setting to be disabled. + Settings.Secure.putInt( + mContext.getContentResolver(), CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, ON); + + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void setChecked_checkToggle_cameraDoubleTapPowerGestureEnabled() { + mController.setChecked(true); + + assertThat( + Settings.Secure.getInt( + mContext.getContentResolver(), + CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, + OFF)) + .isEqualTo(ON); + } + + @Test + public void setChecked_uncheckToggle_cameraDoubleTapPowerGestureDisabled() { + mController.setChecked(false); + + assertThat( + Settings.Secure.getInt( + mContext.getContentResolver(), + CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, + ON)) + .isEqualTo(OFF); + } + + @Test + public void isSliceableCorrectKey_returnsTrue() { + final DoubleTapPowerToOpenCameraPreferenceController controller = + new DoubleTapPowerToOpenCameraPreferenceController( + mContext, "gesture_double_tap_power"); + + assertThat(controller.isSliceable()).isTrue(); + } + + @Test + public void isSliceableIncorrectKey_returnsFalse() { + final DoubleTapPowerToOpenCameraPreferenceController controller = + new DoubleTapPowerToOpenCameraPreferenceController(mContext, "bad_key"); + + assertThat(controller.isSliceable()).isFalse(); + } + + @Test + public void isPublicSlice_returnTrue() { + assertThat(mController.isPublicSlice()).isTrue(); + } +}