diff --git a/res/xml/double_tap_power_settings.xml b/res/xml/double_tap_power_settings.xml new file mode 100644 index 00000000000..b8835ea13f6 --- /dev/null +++ b/res/xml/double_tap_power_settings.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/res/xml/double_tap_screen_settings.xml b/res/xml/double_tap_screen_settings.xml new file mode 100644 index 00000000000..e1ba7c9d3c7 --- /dev/null +++ b/res/xml/double_tap_screen_settings.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/res/xml/double_twist_gesture_settings.xml b/res/xml/double_twist_gesture_settings.xml new file mode 100644 index 00000000000..2cf9d5e3d02 --- /dev/null +++ b/res/xml/double_twist_gesture_settings.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/res/xml/input_and_gesture.xml b/res/xml/input_and_gesture.xml index 0772138ae7c..c30178bb8d9 100644 --- a/res/xml/input_and_gesture.xml +++ b/res/xml/input_and_gesture.xml @@ -38,19 +38,23 @@ + android:title="@string/double_tap_power_for_camera_title" + android:fragment="com.android.settings.gestures.DoubleTapPowerSettings"/> + android:title="@string/double_twist_for_camera_mode_title" + android:fragment="com.android.settings.gestures.DoubleTwistGestureSettings"/> + android:title="@string/ambient_display_title" + android:fragment="com.android.settings.gestures.DoubleTapScreenSettings"/> + android:title="@string/ambient_display_pickup_title" + android:fragment="com.android.settings.gestures.PickupGestureSettings"/> diff --git a/res/xml/pick_up_gesture_settings.xml b/res/xml/pick_up_gesture_settings.xml new file mode 100644 index 00000000000..e335a835c9d --- /dev/null +++ b/res/xml/pick_up_gesture_settings.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index bfadc2434c3..949b6b74e9a 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -97,7 +97,12 @@ import com.android.settings.display.NightDisplaySettings; import com.android.settings.fuelgauge.BatterySaverSettings; import com.android.settings.fuelgauge.PowerUsageDetail; import com.android.settings.fuelgauge.PowerUsageSummary; +import com.android.settings.gestures.DoubleTapPowerSettings; +import com.android.settings.gestures.DoubleTapScreenPreferenceController; +import com.android.settings.gestures.DoubleTapScreenSettings; +import com.android.settings.gestures.DoubleTwistGestureSettings; import com.android.settings.gestures.GestureSettings; +import com.android.settings.gestures.PickupGestureSettings; import com.android.settings.gestures.SwipeToNotificationSettings; import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment; import com.android.settings.inputmethod.InputAndGestureSettings; @@ -350,6 +355,10 @@ public class SettingsActivity extends SettingsDrawerActivity AccountSettings.class.getName(), GestureSettings.class.getName(), SwipeToNotificationSettings.class.getName(), + DoubleTapPowerSettings.class.getName(), + DoubleTapScreenSettings.class.getName(), + PickupGestureSettings.class.getName(), + DoubleTwistGestureSettings.class.getName(), CryptKeeperSettings.class.getName(), DataUsageSummary.class.getName(), DreamSettings.class.getName(), diff --git a/src/com/android/settings/core/InstrumentedFragment.java b/src/com/android/settings/core/InstrumentedFragment.java index 533d2afec6e..45e855eb1db 100644 --- a/src/com/android/settings/core/InstrumentedFragment.java +++ b/src/com/android/settings/core/InstrumentedFragment.java @@ -43,6 +43,10 @@ public abstract class InstrumentedFragment extends ObservablePreferenceFragment protected final int INPUT_AND_GESTURE_CATEGORY_FRAGMENT = PLACEHOLDER_METRIC + 6; protected final int LANGUAGE_AND_REGION_CATEGORY_FRAGMENT = PLACEHOLDER_METRIC + 7; protected final int GESTURE_SWIPE_TO_NOTIFICATION = PLACEHOLDER_METRIC + 8; + protected final int GESTURE_DOUBLE_TAP_POWER = PLACEHOLDER_METRIC + 9; + protected final int GESTURE_PICKUP = PLACEHOLDER_METRIC + 10; + protected final int GESTURE_DOUBLE_TAP_SCREEN = PLACEHOLDER_METRIC + 11; + protected final int GESTURE_DOUBLE_TWIST = PLACEHOLDER_METRIC + 12; public InstrumentedFragment() { // Mixin that logs visibility change for activity. diff --git a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java new file mode 100644 index 00000000000..7838ae785a3 --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java @@ -0,0 +1,78 @@ +/* + * 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.Context; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.support.v7.preference.TwoStatePreference; + +import com.android.settings.core.PreferenceController; + +public class DoubleTapPowerPreferenceController extends PreferenceController + implements Preference.OnPreferenceChangeListener { + + private static final String PREF_KEY_DOUBLE_TAP_POWER = "gesture_double_tap_power"; + + public DoubleTapPowerPreferenceController(Context context) { + super(context); + } + + @Override + public boolean isAvailable() { + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled); + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + return false; + } + + @Override + public String getPreferenceKey() { + return PREF_KEY_DOUBLE_TAP_POWER; + } + + @Override + public void updateState(Preference preference) { + final boolean isEnabled = isDoubleTapEnabled(); + if (preference != null) { + if (preference instanceof TwoStatePreference) { + ((TwoStatePreference) preference).setChecked(isEnabled); + } else { + preference.setSummary(isEnabled + ? com.android.settings.R.string.gesture_setting_on + : com.android.settings.R.string.gesture_setting_off); + } + } + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean enabled = (boolean) newValue; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, enabled ? 0 : 1); + return true; + } + + private boolean isDoubleTapEnabled() { + final int cameraDisabled = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0); + return cameraDisabled == 0; + } +} diff --git a/src/com/android/settings/gestures/DoubleTapPowerSettings.java b/src/com/android/settings/gestures/DoubleTapPowerSettings.java new file mode 100644 index 00000000000..824416528d1 --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapPowerSettings.java @@ -0,0 +1,58 @@ +/* + * 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.Context; + +import com.android.settings.R; +import com.android.settings.core.PreferenceController; +import com.android.settings.dashboard.DashboardFragment; + +import java.util.ArrayList; +import java.util.List; + +public class DoubleTapPowerSettings extends DashboardFragment { + + private static final String TAG = "DoubleTapPower"; + + @Override + public int getMetricsCategory() { + return GESTURE_DOUBLE_TAP_POWER; + } + + @Override + protected String getCategoryKey() { + return null; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.double_tap_power_settings; + } + + @Override + protected List getPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); + controllers.add(new DoubleTapPowerPreferenceController(context)); + return controllers; + } +} diff --git a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java new file mode 100644 index 00000000000..be1c53fdb64 --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java @@ -0,0 +1,80 @@ +/* + * 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.annotation.UserIdInt; +import android.content.Context; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.support.v7.preference.TwoStatePreference; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.core.PreferenceController; + +public class DoubleTapScreenPreferenceController extends PreferenceController + implements Preference.OnPreferenceChangeListener { + + private static final String PREF_KEY_DOUBLE_TAP_SCREEN = "gesture_double_tap_screen"; + + private final AmbientDisplayConfiguration mAmbientConfig; + @UserIdInt + private final int mUserId; + + public DoubleTapScreenPreferenceController(Context context, AmbientDisplayConfiguration config, + @UserIdInt int userId) { + super(context); + mAmbientConfig = config; + mUserId = userId; + } + + @Override + public boolean isAvailable() { + return mAmbientConfig.pulseOnDoubleTapAvailable(); + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + return false; + } + + @Override + public void updateState(Preference preference) { + final boolean isEnabled = mAmbientConfig.pulseOnDoubleTapEnabled(mUserId); + if (preference != null) { + if (preference instanceof TwoStatePreference) { + ((TwoStatePreference) preference).setChecked(isEnabled); + } else { + preference.setSummary(isEnabled + ? com.android.settings.R.string.gesture_setting_on + : com.android.settings.R.string.gesture_setting_off); + } + } + } + + @Override + public String getPreferenceKey() { + return PREF_KEY_DOUBLE_TAP_SCREEN; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean enabled = (boolean) newValue; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, enabled ? 1 : 0); + return true; + } +} diff --git a/src/com/android/settings/gestures/DoubleTapScreenSettings.java b/src/com/android/settings/gestures/DoubleTapScreenSettings.java new file mode 100644 index 00000000000..12e3b64bfe2 --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTapScreenSettings.java @@ -0,0 +1,61 @@ +/* + * 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.Context; +import android.os.UserHandle; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.R; +import com.android.settings.core.PreferenceController; +import com.android.settings.dashboard.DashboardFragment; + +import java.util.ArrayList; +import java.util.List; + +public class DoubleTapScreenSettings extends DashboardFragment { + + private static final String TAG = "DoubleTapScreen"; + + @Override + public int getMetricsCategory() { + return GESTURE_DOUBLE_TAP_SCREEN; + } + + @Override + protected String getCategoryKey() { + return null; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.double_tap_screen_settings; + } + + @Override + protected List getPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); + controllers.add(new DoubleTapScreenPreferenceController( + context, new AmbientDisplayConfiguration(context), UserHandle.myUserId())); + return controllers; + } +} diff --git a/src/com/android/settings/gestures/DoubleTwistGestureSettings.java b/src/com/android/settings/gestures/DoubleTwistGestureSettings.java new file mode 100644 index 00000000000..4f8d2dea315 --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTwistGestureSettings.java @@ -0,0 +1,58 @@ +/* + * 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.Context; + +import com.android.settings.R; +import com.android.settings.core.PreferenceController; +import com.android.settings.dashboard.DashboardFragment; + +import java.util.ArrayList; +import java.util.List; + +public class DoubleTwistGestureSettings extends DashboardFragment { + + private static final String TAG = "DoubleTwistGesture"; + + @Override + public int getMetricsCategory() { + return GESTURE_DOUBLE_TWIST; + } + + @Override + protected String getCategoryKey() { + return null; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.double_twist_gesture_settings; + } + + @Override + protected List getPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); + controllers.add(new DoubleTwistPreferenceController(context)); + return controllers; + } +} diff --git a/src/com/android/settings/gestures/DoubleTwistPreferenceController.java b/src/com/android/settings/gestures/DoubleTwistPreferenceController.java new file mode 100644 index 00000000000..071255ba40c --- /dev/null +++ b/src/com/android/settings/gestures/DoubleTwistPreferenceController.java @@ -0,0 +1,99 @@ +/* + * 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.Context; +import android.content.res.Resources; +import android.hardware.Sensor; +import android.hardware.SensorManager; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.support.v7.preference.TwoStatePreference; +import android.text.TextUtils; + +import com.android.settings.R; +import com.android.settings.core.PreferenceController; + +public class DoubleTwistPreferenceController extends PreferenceController + implements Preference.OnPreferenceChangeListener { + + private static final String PREF_KEY_DOUBLE_TWIST = "gesture_double_twist"; + + public DoubleTwistPreferenceController(Context context) { + super(context); + } + + @Override + public boolean isAvailable() { + return hasSensor(R.string.gesture_double_twist_sensor_name, + R.string.gesture_double_twist_sensor_vendor); + } + + @Override + public void updateState(Preference preference) { + final boolean isEnabled = isDoubleTwistEnabled(); + if (preference != null) { + if (preference instanceof TwoStatePreference) { + ((TwoStatePreference) preference).setChecked(isEnabled); + } else { + preference.setSummary(isEnabled + ? com.android.settings.R.string.gesture_setting_on + : com.android.settings.R.string.gesture_setting_off); + } + } + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + return false; + } + + @Override + public String getPreferenceKey() { + return PREF_KEY_DOUBLE_TWIST; + } + + private boolean isDoubleTwistEnabled() { + final int doubleTwistEnabled = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 1); + return doubleTwistEnabled != 0; + } + + private boolean hasSensor(int nameResId, int vendorResId) { + final Resources resources = mContext.getResources(); + final String name = resources.getString(nameResId); + final String vendor = resources.getString(vendorResId); + if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(vendor)) { + final SensorManager sensorManager = + (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); + for (Sensor s : sensorManager.getSensorList(Sensor.TYPE_ALL)) { + if (name.equals(s.getName()) && vendor.equals(s.getVendor())) { + return true; + } + } + } + return false; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean enabled = (boolean) newValue; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, enabled ? 1 : 0); + return true; + } +} diff --git a/src/com/android/settings/gestures/GestureSettings.java b/src/com/android/settings/gestures/GestureSettings.java index c68d9226065..8ba4d0bc22c 100644 --- a/src/com/android/settings/gestures/GestureSettings.java +++ b/src/com/android/settings/gestures/GestureSettings.java @@ -17,16 +17,11 @@ package com.android.settings.gestures; import android.content.Context; -import android.content.res.Resources; -import android.hardware.Sensor; -import android.hardware.SensorManager; import android.os.Bundle; import android.os.UserHandle; import android.provider.SearchIndexableResource; -import android.provider.Settings.Secure; import android.support.v7.preference.Preference; import android.support.v7.widget.RecyclerView; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -34,7 +29,8 @@ import android.view.ViewGroup; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.PreferenceController; +import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; @@ -46,66 +42,39 @@ import java.util.List; * This will create individual switch preference for each gesture and handle updates when each * preference is updated */ -public class GestureSettings extends SettingsPreferenceFragment implements - Preference.OnPreferenceChangeListener, Indexable { +public class GestureSettings extends DashboardFragment { private static final String TAG = "GestureSettings"; - private static final String PREF_KEY_DOUBLE_TAP_POWER = "gesture_double_tap_power"; - private static final String PREF_KEY_DOUBLE_TWIST = "gesture_double_twist"; - private static final String PREF_KEY_PICK_UP = "gesture_pick_up"; - private static final String PREF_KEY_DOUBLE_TAP_SCREEN = "gesture_double_tap_screen"; - private static final String DEBUG_DOZE_COMPONENT = "debug.doze.component"; - private List mPreferences; - private SwipeToNotificationPreferenceController mSwipeToNotificationPreferenceController; - - private AmbientDisplayConfiguration mAmbientConfig; @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.gesture_settings); - Context context = getActivity(); - mSwipeToNotificationPreferenceController = - new SwipeToNotificationPreferenceController(context); + protected int getPreferenceScreenResId() { + return R.xml.gesture_settings; + } + + @Override + protected List getPreferenceControllers(Context context) { + final AmbientDisplayConfiguration ambientConfig = new AmbientDisplayConfiguration(context); + final List controllers = new ArrayList<>(); + controllers.add(new SwipeToNotificationPreferenceController(context)); + controllers.add(new DoubleTapPowerPreferenceController(context)); + controllers.add(new DoubleTwistPreferenceController(context)); + controllers.add(new PickupGesturePreferenceController( + context, ambientConfig, UserHandle.myUserId())); + controllers.add(new DoubleTapScreenPreferenceController( + context, ambientConfig, UserHandle.myUserId())); + return controllers; + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); mPreferences = new ArrayList(); - - // Double tap power for camera - if (isCameraDoubleTapPowerGestureAvailable(getResources())) { - int cameraDisabled = Secure.getInt( - getContentResolver(), Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0); - addPreference(PREF_KEY_DOUBLE_TAP_POWER, cameraDisabled == 0); - } else { - removePreference(PREF_KEY_DOUBLE_TAP_POWER); - } - - // Ambient Display - mAmbientConfig = new AmbientDisplayConfiguration(context); - if (mAmbientConfig.pulseOnPickupAvailable()) { - boolean pickup = mAmbientConfig.pulseOnPickupEnabled(UserHandle.myUserId()); - addPreference(PREF_KEY_PICK_UP, pickup); - } else { - removePreference(PREF_KEY_PICK_UP); - } - if (mAmbientConfig.pulseOnDoubleTapAvailable()) { - boolean doubleTap = mAmbientConfig.pulseOnDoubleTapEnabled(UserHandle.myUserId()); - addPreference(PREF_KEY_DOUBLE_TAP_SCREEN, doubleTap); - } else { - removePreference(PREF_KEY_DOUBLE_TAP_SCREEN); - } - - // Fingerprint slide for notifications - mSwipeToNotificationPreferenceController.displayPreference(getPreferenceScreen()); - - // Double twist for camera mode - if (isDoubleTwistAvailable(context)) { - int doubleTwistEnabled = Secure.getInt( - getContentResolver(), Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 1); - addPreference(PREF_KEY_DOUBLE_TWIST, doubleTwistEnabled != 0); - } else { - removePreference(PREF_KEY_DOUBLE_TWIST); - } - + addPreferenceToTrackingList(SwipeToNotificationPreferenceController.class); + addPreferenceToTrackingList(DoubleTapScreenPreferenceController.class); + addPreferenceToTrackingList(DoubleTwistPreferenceController.class); + addPreferenceToTrackingList(PickupGesturePreferenceController.class); + addPreferenceToTrackingList(DoubleTapPowerPreferenceController.class); } @Override @@ -134,13 +103,6 @@ public class GestureSettings extends SettingsPreferenceFragment implements return view; } - @Override - public void onResume() { - super.onResume(); - mSwipeToNotificationPreferenceController.updateState( - findPreference(mSwipeToNotificationPreferenceController.getPreferenceKey())); - } - @Override public void onStart() { super.onStart(); @@ -158,21 +120,13 @@ public class GestureSettings extends SettingsPreferenceFragment implements } @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean enabled = (boolean) newValue; - String key = preference.getKey(); - if (PREF_KEY_DOUBLE_TAP_POWER.equals(key)) { - Secure.putInt(getContentResolver(), - Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, enabled ? 0 : 1); - } else if (PREF_KEY_PICK_UP.equals(key)) { - Secure.putInt(getContentResolver(), Secure.DOZE_PULSE_ON_PICK_UP, enabled ? 1 : 0); - } else if (PREF_KEY_DOUBLE_TAP_SCREEN.equals(key)) { - Secure.putInt(getContentResolver(), Secure.DOZE_PULSE_ON_DOUBLE_TAP, enabled ? 1 : 0); - } else if (PREF_KEY_DOUBLE_TWIST.equals(key)) { - Secure.putInt(getContentResolver(), - Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, enabled ? 1 : 0); - } - return true; + protected String getCategoryKey() { + return null; + } + + @Override + protected String getLogTag() { + return TAG; } @Override @@ -185,37 +139,12 @@ public class GestureSettings extends SettingsPreferenceFragment implements return MetricsEvent.SETTINGS_GESTURES; } - private static boolean isCameraDoubleTapPowerGestureAvailable(Resources res) { - return res.getBoolean( - com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled); - } - - private static boolean isDoubleTwistAvailable(Context context) { - return hasSensor(context, R.string.gesture_double_twist_sensor_name, - R.string.gesture_double_twist_sensor_vendor); - } - - private static boolean hasSensor(Context context, int nameResId, int vendorResId) { - Resources resources = context.getResources(); - String name = resources.getString(nameResId); - String vendor = resources.getString(vendorResId); - if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(vendor)) { - SensorManager sensorManager = - (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); - for (Sensor s : sensorManager.getSensorList(Sensor.TYPE_ALL)) { - if (name.equals(s.getName()) && vendor.equals(s.getVendor())) { - return true; - } - } + private void addPreferenceToTrackingList(Class clazz) { + final PreferenceController controller = getPreferenceController(clazz); + final Preference preference = findPreference(controller.getPreferenceKey()); + if (preference != null && preference instanceof GesturePreference) { + mPreferences.add((GesturePreference) preference); } - return false; - } - - private void addPreference(String key, boolean enabled) { - GesturePreference preference = (GesturePreference) findPreference(key); - preference.setChecked(enabled); - preference.setOnPreferenceChangeListener(this); - mPreferences.add(preference); } public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = @@ -238,22 +167,19 @@ public class GestureSettings extends SettingsPreferenceFragment implements ArrayList result = new ArrayList(); AmbientDisplayConfiguration ambientConfig = new AmbientDisplayConfiguration(context); - if (!isCameraDoubleTapPowerGestureAvailable(context.getResources())) { - result.add(PREF_KEY_DOUBLE_TAP_POWER); - } - if (!ambientConfig.pulseOnPickupAvailable()) { - result.add(PREF_KEY_PICK_UP); - } - if (!ambientConfig.pulseOnDoubleTapAvailable()) { - result.add(PREF_KEY_DOUBLE_TAP_SCREEN); - } + new DoubleTapPowerPreferenceController(context) + .updateNonIndexableKeys(result); + new PickupGesturePreferenceController( + context, ambientConfig, UserHandle.myUserId()) + .updateNonIndexableKeys(result); + new DoubleTapScreenPreferenceController( + context, ambientConfig, UserHandle.myUserId()) + .updateNonIndexableKeys(result); new SwipeToNotificationPreferenceController(context) .updateNonIndexableKeys(result); - if (!isDoubleTwistAvailable(context)) { - result.add(PREF_KEY_DOUBLE_TWIST); - } + new DoubleTwistPreferenceController(context) + .updateNonIndexableKeys(result); return result; } }; - } diff --git a/src/com/android/settings/gestures/PickupGesturePreferenceController.java b/src/com/android/settings/gestures/PickupGesturePreferenceController.java new file mode 100644 index 00000000000..b37e756eb01 --- /dev/null +++ b/src/com/android/settings/gestures/PickupGesturePreferenceController.java @@ -0,0 +1,81 @@ +/* + * 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.annotation.UserIdInt; +import android.content.Context; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.support.v7.preference.TwoStatePreference; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.core.PreferenceController; + +public class PickupGesturePreferenceController extends PreferenceController + implements Preference.OnPreferenceChangeListener { + + private static final String PREF_KEY_PICK_UP = "gesture_pick_up"; + + private final AmbientDisplayConfiguration mAmbientConfig; + @UserIdInt + private final int mUserId; + + public PickupGesturePreferenceController(Context context, AmbientDisplayConfiguration config, + @UserIdInt int userId) { + super(context); + mAmbientConfig = config; + mUserId = userId; + } + + @Override + public boolean isAvailable() { + return mAmbientConfig.pulseOnPickupAvailable(); + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + return false; + } + + @Override + public String getPreferenceKey() { + return PREF_KEY_PICK_UP; + } + + @Override + public void updateState(Preference preference) { + final boolean isEnabled = mAmbientConfig.pulseOnPickupEnabled(mUserId); + if (preference != null) { + if (preference instanceof TwoStatePreference) { + ((TwoStatePreference) preference).setChecked(isEnabled); + } else { + preference.setSummary(isEnabled + ? com.android.settings.R.string.gesture_setting_on + : com.android.settings.R.string.gesture_setting_off); + } + } + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean enabled = (boolean) newValue; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.DOZE_PULSE_ON_PICK_UP, enabled ? 1 : 0); + return true; + } + +} diff --git a/src/com/android/settings/gestures/PickupGestureSettings.java b/src/com/android/settings/gestures/PickupGestureSettings.java new file mode 100644 index 00000000000..96f07968f70 --- /dev/null +++ b/src/com/android/settings/gestures/PickupGestureSettings.java @@ -0,0 +1,61 @@ +/* + * 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.Context; +import android.os.UserHandle; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.R; +import com.android.settings.core.PreferenceController; +import com.android.settings.dashboard.DashboardFragment; + +import java.util.ArrayList; +import java.util.List; + +public class PickupGestureSettings extends DashboardFragment { + + private static final String TAG = "PickupGestureSettings"; + + @Override + public int getMetricsCategory() { + return GESTURE_PICKUP; + } + + @Override + protected String getCategoryKey() { + return null; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.pick_up_gesture_settings; + } + + @Override + protected List getPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); + controllers.add(new PickupGesturePreferenceController( + context, new AmbientDisplayConfiguration(context), UserHandle.myUserId())); + return controllers; + } +} diff --git a/src/com/android/settings/inputmethod/InputAndGestureSettings.java b/src/com/android/settings/inputmethod/InputAndGestureSettings.java index c3f0e7b50ba..965cdece80d 100644 --- a/src/com/android/settings/inputmethod/InputAndGestureSettings.java +++ b/src/com/android/settings/inputmethod/InputAndGestureSettings.java @@ -17,10 +17,17 @@ package com.android.settings.inputmethod; import android.content.Context; +import android.os.UserHandle; +import android.support.annotation.VisibleForTesting; +import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.settings.R; import com.android.settings.core.PreferenceController; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.gestures.DoubleTapPowerPreferenceController; +import com.android.settings.gestures.DoubleTapScreenPreferenceController; +import com.android.settings.gestures.DoubleTwistPreferenceController; +import com.android.settings.gestures.PickupGesturePreferenceController; import com.android.settings.gestures.SwipeToNotificationPreferenceController; import com.android.settingslib.drawer.CategoryKey; @@ -31,6 +38,8 @@ public class InputAndGestureSettings extends DashboardFragment { private static final String TAG = "InputAndGestureSettings"; + private AmbientDisplayConfiguration mAmbientDisplayConfig; + @Override public int getMetricsCategory() { return INPUT_AND_GESTURE_CATEGORY_FRAGMENT; @@ -57,10 +66,24 @@ public class InputAndGestureSettings extends DashboardFragment { = new GameControllerPreferenceController(context); getLifecycle().addObserver(gameControllerPreferenceController); + if (mAmbientDisplayConfig == null) { + mAmbientDisplayConfig = new AmbientDisplayConfiguration(context); + } final List controllers = new ArrayList<>(); controllers.add(gameControllerPreferenceController); + // Gestures controllers.add(new SwipeToNotificationPreferenceController(context)); - + controllers.add(new DoubleTwistPreferenceController(context)); + controllers.add(new DoubleTapPowerPreferenceController(context)); + controllers.add(new PickupGesturePreferenceController( + context, mAmbientDisplayConfig, UserHandle.myUserId())); + controllers.add(new DoubleTapScreenPreferenceController( + context, mAmbientDisplayConfig, UserHandle.myUserId())); return controllers; } + + @VisibleForTesting + void setAmbientDisplayConfig(AmbientDisplayConfiguration ambientConfig) { + mAmbientDisplayConfig = ambientConfig; + } } diff --git a/tests/robotests/src/com/android/internal/hardware/AmbientDisplayConfiguration.java b/tests/robotests/src/com/android/internal/hardware/AmbientDisplayConfiguration.java new file mode 100644 index 00000000000..bea9358cff4 --- /dev/null +++ b/tests/robotests/src/com/android/internal/hardware/AmbientDisplayConfiguration.java @@ -0,0 +1,42 @@ +/* + * 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.internal.hardware; + +import android.provider.Settings; + +/** + * Fake controller to make robolectric test compile. Should be removed when Robolectric supports + * API 25. + */ +public class AmbientDisplayConfiguration { + + public boolean pulseOnPickupAvailable() { + return false; + } + + public boolean pulseOnPickupEnabled(int user) { + return true; + } + + public boolean pulseOnDoubleTapAvailable() { + return true; + } + + public boolean pulseOnDoubleTapEnabled(int user) { + return true; + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java new file mode 100644 index 00000000000..9024e0b4c32 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java @@ -0,0 +1,135 @@ +/* + * 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.Context; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.support.v7.preference.TwoStatePreference; + +import com.android.settings.R; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static android.provider.Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class DoubleTapPowerPreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private PreferenceScreen mScreen; + private DoubleTapPowerPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mController = new DoubleTapPowerPreferenceController(mContext); + } + + @Test + public void display_configIsTrue_shouldDisplay() { + when(mContext.getResources(). + getBoolean(com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled)) + .thenReturn(true); + mController.displayPreference(mScreen); + + verify(mScreen, never()).removePreference(any(Preference.class)); + } + + @Test + public void display_configIsFalse_shouldNotDisplay() { + when(mContext.getResources(). + getBoolean(com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled)) + .thenReturn(false); + when(mScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mock(Preference.class)); + + mController.displayPreference(mScreen); + + verify(mScreen).removePreference(any(Preference.class)); + } + + @Test + public void updateState_preferenceSetCheckedWhenSettingIsOn() { + // Mock a TwoStatePreference + final TwoStatePreference preference = mock(TwoStatePreference.class); + // Set the setting to be enabled. + final Context context = ShadowApplication.getInstance().getApplicationContext(); + Settings.System.putInt(context.getContentResolver(), + CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0); + + // Run through updateState + mController = new DoubleTapPowerPreferenceController(context); + mController.updateState(preference); + + // Verify pref is checked (as setting is enabled). + verify(preference).setChecked(true); + } + + @Test + public void updateState_preferenceSetUncheckedWhenSettingIsOff() { + // Mock a TwoStatePreference + final TwoStatePreference preference = mock(TwoStatePreference.class); + // Set the setting to be disabled. + final Context context = ShadowApplication.getInstance().getApplicationContext(); + Settings.System.putInt(context.getContentResolver(), + CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 1); + + // Run through updateState + mController = new DoubleTapPowerPreferenceController(context); + mController.updateState(preference); + + // Verify pref is unchecked (as setting is disabled). + verify(preference).setChecked(false); + } + + @Test + public void updateState_notTwoStatePreference_setSummary() { + // Mock a regular preference + final Preference preference = mock(Preference.class); + // Set the setting to be disabled. + final Context context = ShadowApplication.getInstance().getApplicationContext(); + Settings.System.putInt(context.getContentResolver(), + CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 1); + + // Run through updateState + mController = new DoubleTapPowerPreferenceController(context); + mController.updateState(preference); + + // Verify summary is set to off (as setting is disabled). + verify(preference).setSummary(R.string.gesture_setting_off); + } + +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java new file mode 100644 index 00000000000..1e8020ef15f --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java @@ -0,0 +1,124 @@ +/* + * 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.Context; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.support.v7.preference.TwoStatePreference; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.R; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class DoubleTapScreenPreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private PreferenceScreen mScreen; + @Mock + private AmbientDisplayConfiguration mAmbientDisplayConfiguration; + private DoubleTapScreenPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mController = new DoubleTapScreenPreferenceController( + mContext, mAmbientDisplayConfiguration, 0); + } + + @Test + public void display_configIsTrue_shouldDisplay() { + when(mAmbientDisplayConfiguration.pulseOnDoubleTapAvailable()).thenReturn(true); + + mController.displayPreference(mScreen); + + verify(mScreen, never()).removePreference(any(Preference.class)); + } + + @Test + public void display_configIsFalse_shouldNotDisplay() { + when(mAmbientDisplayConfiguration.pulseOnDoubleTapAvailable()).thenReturn(false); + when(mScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mock(Preference.class)); + + mController.displayPreference(mScreen); + + verify(mScreen).removePreference(any(Preference.class)); + } + + @Test + public void updateState_preferenceSetCheckedWhenSettingIsOn() { + // Mock a TwoStatePreference + final TwoStatePreference preference = mock(TwoStatePreference.class); + // Set the setting to be enabled. + when(mAmbientDisplayConfiguration.pulseOnDoubleTapEnabled(anyInt())).thenReturn(true); + + // Run through updateState + mController.updateState(preference); + + // Verify pref is checked (as setting is enabled). + verify(preference).setChecked(true); + } + + @Test + public void updateState_preferenceSetUncheckedWhenSettingIsOff() { + // Mock a TwoStatePreference + final TwoStatePreference preference = mock(TwoStatePreference.class); + // Set the setting to be disabled. + when(mAmbientDisplayConfiguration.pulseOnDoubleTapEnabled(anyInt())).thenReturn(false); + + // Run through updateState + mController.updateState(preference); + + // Verify pref is unchecked (as setting is disabled). + verify(preference).setChecked(false); + } + + @Test + public void updateState_notTwoStatePreference_setSummary() { + // Mock a regular preference + final Preference preference = mock(Preference.class); + // Set the setting to be disabled. + when(mAmbientDisplayConfiguration.pulseOnDoubleTapEnabled(anyInt())).thenReturn(false); + + // Run through updateState + mController.updateState(preference); + + // Verify summary is set to off (as setting is disabled). + verify(preference).setSummary(R.string.gesture_setting_off); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java new file mode 100644 index 00000000000..8692661309e --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java @@ -0,0 +1,171 @@ +/* + * 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.Context; +import android.hardware.Sensor; +import android.hardware.SensorManager; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.support.v7.preference.TwoStatePreference; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import java.util.ArrayList; +import java.util.List; + +import static android.provider.Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class DoubleTwistPreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private PreferenceScreen mScreen; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private SensorManager mSensorManager; + private DoubleTwistPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mController = new DoubleTwistPreferenceController(mContext); + } + + @Test + public void display_hasSensor_shouldDisplay() { + // Mock sensors + final List sensorList = new ArrayList<>(); + sensorList.add(mock(Sensor.class)); + when(mContext.getResources().getString(anyInt())).thenReturn("test"); + when(mContext.getSystemService(Context.SENSOR_SERVICE)).thenReturn(mSensorManager); + when(mSensorManager.getSensorList(anyInt())).thenReturn(sensorList); + when(sensorList.get(0).getName()).thenReturn("test"); + when(sensorList.get(0).getVendor()).thenReturn("test"); + when(mScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mock(Preference.class)); + + // Run through display + mController.displayPreference(mScreen); + + // Verify preference is not removed + verify(mScreen, never()).removePreference(any(Preference.class)); + } + + @Test + public void display_noSensor_shouldNotDisplay() { + when(mScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mock(Preference.class)); + + mController.displayPreference(mScreen); + + verify(mScreen).removePreference(any(Preference.class)); + } + + @Test + public void display_differentSensor_shouldNotDisplay() { + // Mock sensors + final List sensorList = new ArrayList<>(); + sensorList.add(mock(Sensor.class)); + when(mContext.getResources().getString(anyInt())).thenReturn("test"); + when(mContext.getSystemService(Context.SENSOR_SERVICE)).thenReturn(mSensorManager); + when(mSensorManager.getSensorList(anyInt())).thenReturn(sensorList); + when(sensorList.get(0).getName()).thenReturn("not_test"); + when(mScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mock(Preference.class)); + when(mScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mock(Preference.class)); + + // Run through display + mController.displayPreference(mScreen); + + // Verify preference is not removed + verify(mScreen).removePreference(any(Preference.class)); + } + + + @Test + public void updateState_preferenceSetCheckedWhenSettingIsOn() { + // Mock a TwoStatePreference + final TwoStatePreference preference = mock(TwoStatePreference.class); + // Set the setting to be enabled. + final Context context = ShadowApplication.getInstance().getApplicationContext(); + Settings.System.putInt(context.getContentResolver(), + CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 1); + + // Run through updateState + mController = new DoubleTwistPreferenceController(context); + mController.updateState(preference); + + // Verify pref is checked (as setting is enabled). + verify(preference).setChecked(true); + } + + @Test + public void updateState_preferenceSetUncheckedWhenSettingIsOff() { + // Mock a TwoStatePreference + final TwoStatePreference preference = mock(TwoStatePreference.class); + // Set the setting to be disabled. + final Context context = ShadowApplication.getInstance().getApplicationContext(); + Settings.System.putInt(context.getContentResolver(), + CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 0); + + // Run through updateState + mController = new DoubleTwistPreferenceController(context); + mController.updateState(preference); + + // Verify pref is unchecked (as setting is disabled). + verify(preference).setChecked(false); + } + + @Test + public void updateState_notTwoStatePreference_setSummary() { + // Mock a regular preference + final Preference preference = mock(Preference.class); + // Set the setting to be disabled. + final Context context = ShadowApplication.getInstance().getApplicationContext(); + Settings.System.putInt(context.getContentResolver(), + CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 0); + + // Run through updateState + mController = new DoubleTwistPreferenceController(context); + mController.updateState(preference); + + // Verify summary is set to off (as setting is disabled). + verify(preference).setSummary(com.android.settings.R.string.gesture_setting_off); + } + +} diff --git a/tests/robotests/src/com/android/settings/gestures/PIckupGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PIckupGesturePreferenceControllerTest.java new file mode 100644 index 00000000000..217d0b82f93 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/PIckupGesturePreferenceControllerTest.java @@ -0,0 +1,126 @@ +/* + * 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.Context; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.support.v7.preference.TwoStatePreference; + +import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.settings.R; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class PIckupGesturePreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private PreferenceScreen mScreen; + @Mock + private AmbientDisplayConfiguration mAmbientDisplayConfiguration; + + private PickupGesturePreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mController = new PickupGesturePreferenceController( + mContext, mAmbientDisplayConfiguration, 0); + } + + @Test + public void display_configIsTrue_shouldDisplay() { + when(mAmbientDisplayConfiguration.pulseOnPickupAvailable()).thenReturn(true); + + mController.displayPreference(mScreen); + + verify(mScreen, never()).removePreference(any(Preference.class)); + } + + @Test + public void display_configIsFalse_shouldNotDisplay() { + when(mAmbientDisplayConfiguration.pulseOnPickupAvailable()).thenReturn(false); + when(mScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mock(Preference.class)); + + mController.displayPreference(mScreen); + + verify(mScreen).removePreference(any(Preference.class)); + } + + @Test + public void updateState_preferenceSetCheckedWhenSettingIsOn() { + // Mock a TwoStatePreference + final TwoStatePreference preference = mock(TwoStatePreference.class); + // Set the setting to be enabled. + when(mAmbientDisplayConfiguration.pulseOnPickupEnabled(anyInt())).thenReturn(true); + + // Run through updateState + mController.updateState(preference); + + // Verify pref is checked (as setting is enabled). + verify(preference).setChecked(true); + } + + @Test + public void updateState_preferenceSetUncheckedWhenSettingIsOff() { + // Mock a TwoStatePreference + final TwoStatePreference preference = mock(TwoStatePreference.class); + // Set the setting to be disabled. + when(mAmbientDisplayConfiguration.pulseOnPickupEnabled(anyInt())).thenReturn(false); + + // Run through updateState + mController.updateState(preference); + + // Verify pref is unchecked (as setting is disabled). + verify(preference).setChecked(false); + } + + @Test + public void updateState_notTwoStatePreference_setSummary() { + // Mock a regular preference + final Preference preference = mock(Preference.class); + // Set the setting to be disabled. + when(mAmbientDisplayConfiguration.pulseOnPickupEnabled(anyInt())).thenReturn(false); + + // Run through updateState + mController.updateState(preference); + + // Verify summary is set to off (as setting is disabled). + verify(preference).setSummary(R.string.gesture_setting_off); + } + +} diff --git a/tests/robotests/src/com/android/settings/inputmethod/InputAndGestureSettingsTest.java b/tests/robotests/src/com/android/settings/inputmethod/InputAndGestureSettingsTest.java index f51ee56f69e..ce8ed1c7041 100644 --- a/tests/robotests/src/com/android/settings/inputmethod/InputAndGestureSettingsTest.java +++ b/tests/robotests/src/com/android/settings/inputmethod/InputAndGestureSettingsTest.java @@ -19,6 +19,7 @@ package com.android.settings.inputmethod; import android.content.Context; import android.hardware.input.InputManager; +import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; @@ -76,6 +77,9 @@ public class InputAndGestureSettingsTest { .addObserver(any(LifecycleObserver.class)); } + /** + * Test fragment to expose lifecycle and context so we can verify behavior for observables. + */ public static class TestFragment extends InputAndGestureSettings { private Lifecycle mLifecycle; @@ -84,6 +88,7 @@ public class InputAndGestureSettingsTest { public TestFragment(Context context) { mContext = context; mLifecycle = mock(Lifecycle.class); + setAmbientDisplayConfig(mock(AmbientDisplayConfiguration.class)); } @Override