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()); + } +}