diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 562f89b3aea..09ee4243287 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3078,6 +3078,24 @@
android:permission="android.permission.DUMP"
android:enabled="@bool/config_has_help" />
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable-nodpi/gesture_camera_lift b/res/drawable-nodpi/gesture_camera_lift
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/res/raw/gesture_camera_lift.mp4 b/res/raw/gesture_camera_lift.mp4
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/res/values/config.xml b/res/values/config.xml
index f81bf9b3e38..5aaf426e4ee 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -99,4 +99,7 @@
-->
+
+ false
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 05d6b5b80ea..48d492243fd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8413,6 +8413,15 @@
To check your notifications, swipe down on the fingerprint sensor on the back of your device.
+
+ Lift to open camera
+
+
+ To open the camera automatically, lift up your phone into a photo-taking position (landscape or portrait). Works when your phone is asleep or locked.
+
+
+ Never miss a moment
+
Assist gesture
diff --git a/res/xml/camera_lift_trigger_settings.xml b/res/xml/camera_lift_trigger_settings.xml
new file mode 100644
index 00000000000..fe8991a8ec2
--- /dev/null
+++ b/res/xml/camera_lift_trigger_settings.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml
index 17bd576f32d..6a9a3ad5d24 100644
--- a/res/xml/language_and_input.xml
+++ b/res/xml/language_and_input.xml
@@ -75,16 +75,6 @@
android:title="@string/fingerprint_swipe_for_notifications_title"
android:fragment="com.android.settings.gestures.SwipeToNotificationSettings"/>
-
-
-
-
+
+
+
+
+
+
getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getLifecycle());
+ }
+
+ private static List buildPreferenceControllers(Context context,
+ Lifecycle lifecycle) {
+ final List controllers = new ArrayList<>();
+ controllers.add(new CameraLiftTriggerPreferenceController(context, lifecycle, KEY));
+ return controllers;
+ }
+
+ public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.camera_lift_trigger_settings;
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, null /* lifecycle */);
+ }
+ };
+}
diff --git a/src/com/android/settings/language/LanguageAndInputSettings.java b/src/com/android/settings/language/LanguageAndInputSettings.java
index 86ce118fb98..f411bca8a04 100644
--- a/src/com/android/settings/language/LanguageAndInputSettings.java
+++ b/src/com/android/settings/language/LanguageAndInputSettings.java
@@ -37,6 +37,7 @@ import com.android.settings.core.lifecycle.Lifecycle;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.gestures.AssistGesturePreferenceController;
+import com.android.settings.gestures.CameraLiftTriggerPreferenceController;
import com.android.settings.gestures.DoubleTapPowerPreferenceController;
import com.android.settings.gestures.DoubleTapScreenPreferenceController;
import com.android.settings.gestures.DoubleTwistPreferenceController;
@@ -56,6 +57,8 @@ public class LanguageAndInputSettings extends DashboardFragment {
private static final String TAG = "LangAndInputSettings";
+ private static final String KEY_CAMERA_LIFT_TRIGGER = "gesture_camera_lift_trigger_summary";
+
private AmbientDisplayConfiguration mAmbientDisplayConfig;
@Override
@@ -108,6 +111,8 @@ public class LanguageAndInputSettings extends DashboardFragment {
context, lifecycle, mAmbientDisplayConfig, UserHandle.myUserId()));
controllers.add(new DoubleTapScreenPreferenceController(
context, lifecycle, mAmbientDisplayConfig, UserHandle.myUserId()));
+ controllers.add(new CameraLiftTriggerPreferenceController(context, lifecycle,
+ KEY_CAMERA_LIFT_TRIGGER));
controllers.add(new DefaultAutofillPreferenceController(context));
return controllers;
}
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index f7882ae5572..1d4e5f7ba25 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -57,6 +57,7 @@ import com.android.settings.gestures.DoubleTapScreenSettings;
import com.android.settings.gestures.DoubleTwistGestureSettings;
import com.android.settings.gestures.PickupGestureSettings;
import com.android.settings.gestures.SwipeToNotificationSettings;
+import com.android.settings.gestures.CameraLiftTriggerSettings;
import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
import com.android.settings.inputmethod.PhysicalKeyboardFragment;
import com.android.settings.inputmethod.VirtualKeyboardFragment;
@@ -140,6 +141,8 @@ public final class SearchIndexableResources {
addIndex(DoubleTwistGestureSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_gestures);
addIndex(SwipeToNotificationSettings.class, NO_DATA_RES_ID,
R.drawable.ic_settings_gestures);
+ addIndex(CameraLiftTriggerSettings.class, NO_DATA_RES_ID,
+ R.drawable.ic_settings_gestures);
addIndex(LanguageAndInputSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_language);
addIndex(LocationSettings.class, R.xml.location_settings, R.drawable.ic_settings_location);
addIndex(ScanningSettings.class, R.xml.location_scanning, R.drawable.ic_settings_location);
diff --git a/tests/robotests/src/com/android/settings/gestures/CameraLiftTriggerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/CameraLiftTriggerPreferenceControllerTest.java
new file mode 100644
index 00000000000..2f12a01d9a7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/gestures/CameraLiftTriggerPreferenceControllerTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 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.PreferenceScreen;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import com.android.settings.R;
+import com.android.settings.search2.InlineSwitchPayload;
+import com.android.settings.search2.ResultPayload;
+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.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import static android.provider.Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class CameraLiftTriggerPreferenceControllerTest {
+
+ private static final String KEY_CAMERA_LIFT_TRIGGER = "gesture_camera_lift_trigger";
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private PreferenceScreen mScreen;
+ private CameraLiftTriggerPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mController = new CameraLiftTriggerPreferenceController(mContext, null,
+ KEY_CAMERA_LIFT_TRIGGER);
+ }
+
+ @Test
+ public void isAvailable_configIsTrue_shouldReturnTrue() {
+ when(mContext.getResources().
+ getBoolean(R.bool.config_cameraLiftTriggerAvailable))
+ .thenReturn(true);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_configIsTrue_shouldReturnFalse() {
+ when(mContext.getResources().
+ getBoolean(R.bool.config_cameraLiftTriggerAvailable))
+ .thenReturn(false);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void testSwitchEnabled_configIsNotSet_shouldReturnFalse() {
+ // Set the setting to be enabled.
+ final Context context = RuntimeEnvironment.application;
+ Settings.System.putInt(context.getContentResolver(),
+ CAMERA_LIFT_TRIGGER_ENABLED, 0);
+ mController = new CameraLiftTriggerPreferenceController(context, null,
+ KEY_CAMERA_LIFT_TRIGGER);
+
+ assertThat(mController.isSwitchPrefEnabled()).isFalse();
+ }
+
+ @Test
+ public void testSwitchEnabled_configIsSet_shouldReturnTrue() {
+ // Set the setting to be disabled.
+ final Context context = RuntimeEnvironment.application;
+ Settings.System.putInt(context.getContentResolver(),
+ CAMERA_LIFT_TRIGGER_ENABLED, 1);
+ mController = new CameraLiftTriggerPreferenceController(context, null,
+ KEY_CAMERA_LIFT_TRIGGER);
+
+ assertThat(mController.isSwitchPrefEnabled()).isTrue();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/CameraLiftTriggerSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/CameraLiftTriggerSettingsTest.java
new file mode 100644
index 00000000000..681fa3a0502
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/gestures/CameraLiftTriggerSettingsTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 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.provider.SearchIndexableResource;
+
+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.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.List;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class CameraLiftTriggerSettingsTest {
+
+ private CameraLiftTriggerSettings mSettings;
+
+ @Before
+ public void setUp() {
+ mSettings = new CameraLiftTriggerSettings();
+ }
+
+ @Test
+ public void testSearchIndexProvider_shouldIndexResource() {
+ final List indexRes =
+ CameraLiftTriggerSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
+ ShadowApplication.getInstance().getApplicationContext(),
+ true /* enabled */);
+
+ assertThat(indexRes).isNotNull();
+ assertThat(indexRes.get(0).xmlResId).isEqualTo(mSettings.getPreferenceScreenResId());
+ }
+}