Add more gesture setting pages.

Bug: 32637613
Test: make -j40 RunSettingsRoboTests
Change-Id: I77f90b8b7e3348ed717ee78693860f48e13070f2
This commit is contained in:
Fan Zhang
2016-11-08 13:52:58 -08:00
parent b52c50d01d
commit b99ea90046
23 changed files with 1375 additions and 130 deletions

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:key="gesture_double_tap_power"
android:title="@string/double_tap_power_for_camera_title"
android:summary="@string/double_tap_power_for_camera_summary"/>
</PreferenceScreen>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:key="gesture_double_tap_screen"
android:title="@string/ambient_display_title"
android:summary="@string/ambient_display_summary"/>
</PreferenceScreen>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:key="gesture_double_twist"
android:title="@string/double_twist_for_camera_mode_title"
android:summary="@string/double_twist_for_camera_mode_summary"/>
</PreferenceScreen>

View File

@@ -38,19 +38,23 @@
<Preference <Preference
android:key="gesture_double_tap_power" android:key="gesture_double_tap_power"
android:title="@string/double_tap_power_for_camera_title"/> android:title="@string/double_tap_power_for_camera_title"
android:fragment="com.android.settings.gestures.DoubleTapPowerSettings"/>
<Preference <Preference
android:key="gesture_double_twist" android:key="gesture_double_twist"
android:title="@string/double_twist_for_camera_mode_title"/> android:title="@string/double_twist_for_camera_mode_title"
android:fragment="com.android.settings.gestures.DoubleTwistGestureSettings"/>
<Preference <Preference
android:key="gesture_double_tap_screen" android:key="gesture_double_tap_screen"
android:title="@string/ambient_display_title"/> android:title="@string/ambient_display_title"
android:fragment="com.android.settings.gestures.DoubleTapScreenSettings"/>
<Preference <Preference
android:key="gesture_pick_up" android:key="gesture_pick_up"
android:title="@string/ambient_display_pickup_title"/> android:title="@string/ambient_display_pickup_title"
android:fragment="com.android.settings.gestures.PickupGestureSettings"/>
</PreferenceCategory> </PreferenceCategory>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:key="gesture_pick_up"
android:title="@string/ambient_display_pickup_title"
android:summary="@string/ambient_display_pickup_summary"/>
</PreferenceScreen>

View File

@@ -97,7 +97,12 @@ import com.android.settings.display.NightDisplaySettings;
import com.android.settings.fuelgauge.BatterySaverSettings; import com.android.settings.fuelgauge.BatterySaverSettings;
import com.android.settings.fuelgauge.PowerUsageDetail; import com.android.settings.fuelgauge.PowerUsageDetail;
import com.android.settings.fuelgauge.PowerUsageSummary; 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.GestureSettings;
import com.android.settings.gestures.PickupGestureSettings;
import com.android.settings.gestures.SwipeToNotificationSettings; import com.android.settings.gestures.SwipeToNotificationSettings;
import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment; import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
import com.android.settings.inputmethod.InputAndGestureSettings; import com.android.settings.inputmethod.InputAndGestureSettings;
@@ -350,6 +355,10 @@ public class SettingsActivity extends SettingsDrawerActivity
AccountSettings.class.getName(), AccountSettings.class.getName(),
GestureSettings.class.getName(), GestureSettings.class.getName(),
SwipeToNotificationSettings.class.getName(), SwipeToNotificationSettings.class.getName(),
DoubleTapPowerSettings.class.getName(),
DoubleTapScreenSettings.class.getName(),
PickupGestureSettings.class.getName(),
DoubleTwistGestureSettings.class.getName(),
CryptKeeperSettings.class.getName(), CryptKeeperSettings.class.getName(),
DataUsageSummary.class.getName(), DataUsageSummary.class.getName(),
DreamSettings.class.getName(), DreamSettings.class.getName(),

View File

@@ -43,6 +43,10 @@ public abstract class InstrumentedFragment extends ObservablePreferenceFragment
protected final int INPUT_AND_GESTURE_CATEGORY_FRAGMENT = PLACEHOLDER_METRIC + 6; 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 LANGUAGE_AND_REGION_CATEGORY_FRAGMENT = PLACEHOLDER_METRIC + 7;
protected final int GESTURE_SWIPE_TO_NOTIFICATION = PLACEHOLDER_METRIC + 8; 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() { public InstrumentedFragment() {
// Mixin that logs visibility change for activity. // Mixin that logs visibility change for activity.

View File

@@ -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;
}
}

View File

@@ -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<PreferenceController> getPreferenceControllers(Context context) {
final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new DoubleTapPowerPreferenceController(context));
return controllers;
}
}

View File

@@ -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;
}
}

View File

@@ -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<PreferenceController> getPreferenceControllers(Context context) {
final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new DoubleTapScreenPreferenceController(
context, new AmbientDisplayConfiguration(context), UserHandle.myUserId()));
return controllers;
}
}

View File

@@ -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<PreferenceController> getPreferenceControllers(Context context) {
final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new DoubleTwistPreferenceController(context));
return controllers;
}
}

View File

@@ -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;
}
}

View File

@@ -17,16 +17,11 @@
package com.android.settings.gestures; package com.android.settings.gestures;
import android.content.Context; import android.content.Context;
import android.content.res.Resources;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.SearchIndexableResource; import android.provider.SearchIndexableResource;
import android.provider.Settings.Secure;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -34,7 +29,8 @@ import android.view.ViewGroup;
import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.R; 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.BaseSearchIndexProvider;
import com.android.settings.search.Indexable; 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 * This will create individual switch preference for each gesture and handle updates when each
* preference is updated * preference is updated
*/ */
public class GestureSettings extends SettingsPreferenceFragment implements public class GestureSettings extends DashboardFragment {
Preference.OnPreferenceChangeListener, Indexable {
private static final String TAG = "GestureSettings"; 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<GesturePreference> mPreferences; private List<GesturePreference> mPreferences;
private SwipeToNotificationPreferenceController mSwipeToNotificationPreferenceController;
private AmbientDisplayConfiguration mAmbientConfig;
@Override @Override
public void onCreate(Bundle savedInstanceState) { protected int getPreferenceScreenResId() {
super.onCreate(savedInstanceState); return R.xml.gesture_settings;
addPreferencesFromResource(R.xml.gesture_settings); }
Context context = getActivity();
mSwipeToNotificationPreferenceController = @Override
new SwipeToNotificationPreferenceController(context); protected List<PreferenceController> getPreferenceControllers(Context context) {
final AmbientDisplayConfiguration ambientConfig = new AmbientDisplayConfiguration(context);
final List<PreferenceController> 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(); mPreferences = new ArrayList();
addPreferenceToTrackingList(SwipeToNotificationPreferenceController.class);
// Double tap power for camera addPreferenceToTrackingList(DoubleTapScreenPreferenceController.class);
if (isCameraDoubleTapPowerGestureAvailable(getResources())) { addPreferenceToTrackingList(DoubleTwistPreferenceController.class);
int cameraDisabled = Secure.getInt( addPreferenceToTrackingList(PickupGesturePreferenceController.class);
getContentResolver(), Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0); addPreferenceToTrackingList(DoubleTapPowerPreferenceController.class);
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);
}
} }
@Override @Override
@@ -134,13 +103,6 @@ public class GestureSettings extends SettingsPreferenceFragment implements
return view; return view;
} }
@Override
public void onResume() {
super.onResume();
mSwipeToNotificationPreferenceController.updateState(
findPreference(mSwipeToNotificationPreferenceController.getPreferenceKey()));
}
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
@@ -158,21 +120,13 @@ public class GestureSettings extends SettingsPreferenceFragment implements
} }
@Override @Override
public boolean onPreferenceChange(Preference preference, Object newValue) { protected String getCategoryKey() {
boolean enabled = (boolean) newValue; return null;
String key = preference.getKey(); }
if (PREF_KEY_DOUBLE_TAP_POWER.equals(key)) {
Secure.putInt(getContentResolver(), @Override
Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, enabled ? 0 : 1); protected String getLogTag() {
} else if (PREF_KEY_PICK_UP.equals(key)) { return TAG;
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;
} }
@Override @Override
@@ -185,37 +139,12 @@ public class GestureSettings extends SettingsPreferenceFragment implements
return MetricsEvent.SETTINGS_GESTURES; return MetricsEvent.SETTINGS_GESTURES;
} }
private static boolean isCameraDoubleTapPowerGestureAvailable(Resources res) { private <T extends PreferenceController> void addPreferenceToTrackingList(Class<T> clazz) {
return res.getBoolean( final PreferenceController controller = getPreferenceController(clazz);
com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled); final Preference preference = findPreference(controller.getPreferenceKey());
} if (preference != null && preference instanceof GesturePreference) {
mPreferences.add((GesturePreference) preference);
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;
}
}
} }
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 = public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
@@ -238,22 +167,19 @@ public class GestureSettings extends SettingsPreferenceFragment implements
ArrayList<String> result = new ArrayList<String>(); ArrayList<String> result = new ArrayList<String>();
AmbientDisplayConfiguration ambientConfig AmbientDisplayConfiguration ambientConfig
= new AmbientDisplayConfiguration(context); = new AmbientDisplayConfiguration(context);
if (!isCameraDoubleTapPowerGestureAvailable(context.getResources())) { new DoubleTapPowerPreferenceController(context)
result.add(PREF_KEY_DOUBLE_TAP_POWER); .updateNonIndexableKeys(result);
} new PickupGesturePreferenceController(
if (!ambientConfig.pulseOnPickupAvailable()) { context, ambientConfig, UserHandle.myUserId())
result.add(PREF_KEY_PICK_UP); .updateNonIndexableKeys(result);
} new DoubleTapScreenPreferenceController(
if (!ambientConfig.pulseOnDoubleTapAvailable()) { context, ambientConfig, UserHandle.myUserId())
result.add(PREF_KEY_DOUBLE_TAP_SCREEN); .updateNonIndexableKeys(result);
}
new SwipeToNotificationPreferenceController(context) new SwipeToNotificationPreferenceController(context)
.updateNonIndexableKeys(result); .updateNonIndexableKeys(result);
if (!isDoubleTwistAvailable(context)) { new DoubleTwistPreferenceController(context)
result.add(PREF_KEY_DOUBLE_TWIST); .updateNonIndexableKeys(result);
}
return result; return result;
} }
}; };
} }

View File

@@ -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;
}
}

View File

@@ -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<PreferenceController> getPreferenceControllers(Context context) {
final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(new PickupGesturePreferenceController(
context, new AmbientDisplayConfiguration(context), UserHandle.myUserId()));
return controllers;
}
}

View File

@@ -17,10 +17,17 @@
package com.android.settings.inputmethod; package com.android.settings.inputmethod;
import android.content.Context; 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.R;
import com.android.settings.core.PreferenceController; import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.DashboardFragment; 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.settings.gestures.SwipeToNotificationPreferenceController;
import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.CategoryKey;
@@ -31,6 +38,8 @@ public class InputAndGestureSettings extends DashboardFragment {
private static final String TAG = "InputAndGestureSettings"; private static final String TAG = "InputAndGestureSettings";
private AmbientDisplayConfiguration mAmbientDisplayConfig;
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return INPUT_AND_GESTURE_CATEGORY_FRAGMENT; return INPUT_AND_GESTURE_CATEGORY_FRAGMENT;
@@ -57,10 +66,24 @@ public class InputAndGestureSettings extends DashboardFragment {
= new GameControllerPreferenceController(context); = new GameControllerPreferenceController(context);
getLifecycle().addObserver(gameControllerPreferenceController); getLifecycle().addObserver(gameControllerPreferenceController);
if (mAmbientDisplayConfig == null) {
mAmbientDisplayConfig = new AmbientDisplayConfiguration(context);
}
final List<PreferenceController> controllers = new ArrayList<>(); final List<PreferenceController> controllers = new ArrayList<>();
controllers.add(gameControllerPreferenceController); controllers.add(gameControllerPreferenceController);
// Gestures
controllers.add(new SwipeToNotificationPreferenceController(context)); 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; return controllers;
} }
@VisibleForTesting
void setAmbientDisplayConfig(AmbientDisplayConfiguration ambientConfig) {
mAmbientDisplayConfig = ambientConfig;
}
} }

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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<Sensor> 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<Sensor> 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);
}
}

View File

@@ -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);
}
}

View File

@@ -19,6 +19,7 @@ package com.android.settings.inputmethod;
import android.content.Context; import android.content.Context;
import android.hardware.input.InputManager; import android.hardware.input.InputManager;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
@@ -76,6 +77,9 @@ public class InputAndGestureSettingsTest {
.addObserver(any(LifecycleObserver.class)); .addObserver(any(LifecycleObserver.class));
} }
/**
* Test fragment to expose lifecycle and context so we can verify behavior for observables.
*/
public static class TestFragment extends InputAndGestureSettings { public static class TestFragment extends InputAndGestureSettings {
private Lifecycle mLifecycle; private Lifecycle mLifecycle;
@@ -84,6 +88,7 @@ public class InputAndGestureSettingsTest {
public TestFragment(Context context) { public TestFragment(Context context) {
mContext = context; mContext = context;
mLifecycle = mock(Lifecycle.class); mLifecycle = mock(Lifecycle.class);
setAmbientDisplayConfig(mock(AmbientDisplayConfiguration.class));
} }
@Override @Override