5/n: Add face settings
This change connects the face status preference controller with the
settings fragment/activity. This change also implements the basic settings
page showing a video, a toggle for keyguard, improve/remove targets,
and footer.
Bug: 111321762
Test: manual
Change-Id: Ifc65f5acbf6551679074df63ef22ffba75229f37
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c1e0c60..b4dcd9c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -425,6 +425,17 @@
android:value="com.android.settings.gestures.AssistGestureSettings" />
</activity>
+ <activity android:name="Settings$FaceSettingsActivity"
+ android:label="@string/security_settings_face_preference_title"
+ android:icon="@drawable/ic_face_header">
+ <intent-filter>
+ <action android:name="android.settings.FACE_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.biometrics.face.FaceSettings" />
+ </activity>
+
<activity android:name=".bluetooth.DevicePickerActivity"
android:label="@string/device_picker"
android:configChanges="orientation|keyboardHidden|screenSize"
diff --git a/res/layout/face_remove_button.xml b/res/layout/face_remove_button.xml
new file mode 100644
index 0000000..7fd28b6
--- /dev/null
+++ b/res/layout/face_remove_button.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2018 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/security_settings_face_settings_remove_button"
+ android:layout_marginStart="@dimen/screen_margin_sides"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start"
+ android:text="@string/security_settings_face_settings_remove_face_data"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f284e30..5a49147 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -887,6 +887,17 @@
<string name="security_settings_face_enroll_finish_title">All set. Looking good.</string>
<!-- Button text to exit face wizard after everything is done [CHAR LIMIT=15] -->
<string name="security_settings_face_enroll_done">Done</string>
+ <!-- Title for a category shown for the face settings page. [CHAR LIMIT=20] -->
+ <string name="security_settings_face_settings_use_face_category">Use your face to</string>
+ <!-- Text shown on a toggle which allows or disallows the device to use face for unlocking the device. [CHAR LIMIT=20] -->
+ <string name="security_settings_face_settings_use_face_unlock_phone">Unlock your device</string>
+ <!-- Button text in face settings which removes the user's faces from the device [CHAR LIMIT=20] -->
+ <string name="security_settings_face_settings_remove_face_data">Remove face data</string>
+ <!-- Text shown in face settings allowing the user to update/improve the enrolled face. This brings the user back to the enrollment flow. [CHAR LIMIT=30] -->
+ <string name="security_settings_face_settings_improve_face">Improve your face data</string>
+ <!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer">Your face can be used to unlock your device and access apps.
+ <annotation id="url">Learn more</annotation></string>
<!-- Fingerprint enrollment and settings --><skip />
<!-- Title shown for menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
@@ -6634,6 +6645,8 @@
<string name="help_url_nfc_payment" translatable="false"></string>
<!-- Help URL, Remote display [DO NOT TRANSLATE] -->
<string name="help_url_remote_display" translatable="false"></string>
+ <!-- Help URL, Face [DO NOT TRANSLATE] -->
+ <string name="help_url_face" translatable="false"></string>
<!-- Help URL, Fingerprint [DO NOT TRANSLATE] -->
<string name="help_url_fingerprint" translatable="false"></string>
<!-- Help URL, Gesture settings -->
@@ -6962,6 +6975,7 @@
<string name="keywords_payment_settings">pay, tap, payments</string>
<string name="keywords_backup">backup, back up</string>
<string name="keywords_assist_gesture_launch">gesture</string>
+ <string name="keywords_face_unlock">face, unlock</string>
<string name="keywords_imei_info">imei, meid, min, prl version, imei sv</string>
<string name="keywords_sim_status">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid</string>
<string name="keywords_model_and_hardware">serial number, hardware version</string>
diff --git a/res/xml/security_settings_face.xml b/res/xml/security_settings_face.xml
new file mode 100644
index 0000000..3dfcfd7
--- /dev/null
+++ b/res/xml/security_settings_face.xml
@@ -0,0 +1,56 @@
+<!--
+ ~ Copyright (C) 2018 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"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:key="security_settings_face_settings_page"
+ android:title="@string/security_settings_face_preference_title">
+
+ <com.android.settings.widget.VideoPreference
+ android:key="security_settings_face_video"
+ app:animation="@raw/gesture_fingerprint_swipe"
+ app:preview="@drawable/face_enroll_introduction" />
+
+ <PreferenceCategory
+ android:key="security_settings_face_unlock_category"
+ android:title="@string/security_settings_face_settings_use_face_category">
+ <SwitchPreference
+ android:key="security_settings_face_unlock"
+ android:title="@string/security_settings_face_settings_use_face_unlock_phone"
+ app:keywords="@string/keywords_face_unlock"
+ app:controller="com.android.settings.biometrics.face.FaceSettingsUnlockPreferenceController"/>
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:key="security_settings_face_manage_category">
+ <Preference
+ android:key="security_settings_face_improve"
+ android:title="@string/security_settings_face_settings_improve_face">
+ </Preference>
+
+ <com.android.settings.applications.LayoutPreference
+ android:key="security_settings_face_delete_faces_container"
+ android:selectable="false"
+ android:layout="@layout/face_remove_button" />
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:key="security_settings_face_footer_container">
+ <com.android.settingslib.widget.FooterPreference />
+ </PreferenceCategory>
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 99d7d47..4f011c1 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -31,6 +31,7 @@
public static class AssistGestureSettingsActivity extends SettingsActivity { /* empty */}
public static class BluetoothSettingsActivity extends SettingsActivity { /* empty */ }
public static class CreateShortcutActivity extends SettingsActivity { /* empty */ }
+ public static class FaceSettingsActivity extends SettingsActivity { /* empty */ }
public static class SimSettingsActivity extends SettingsActivity { /* empty */ }
public static class TetherSettingsActivity extends SettingsActivity { /* empty */ }
public static class WifiTetherSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/biometrics/BiometricEnrollBase.java b/src/com/android/settings/biometrics/BiometricEnrollBase.java
index 298891e..130f20f 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollBase.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollBase.java
@@ -16,6 +16,8 @@
package com.android.settings.biometrics;
+import static android.app.Activity.RESULT_FIRST_USER;
+
import android.annotation.Nullable;
import android.content.Intent;
import android.content.res.Resources;
@@ -39,11 +41,33 @@
*/
public abstract class BiometricEnrollBase extends InstrumentedActivity
implements View.OnClickListener {
- public static final int RESULT_FINISHED = BiometricSettings.RESULT_FINISHED;
- public static final int RESULT_SKIP = BiometricSettings.RESULT_SKIP;
- public static final int RESULT_TIMEOUT = BiometricSettings.RESULT_TIMEOUT;
public static final String EXTRA_KEY_LAUNCHED_CONFIRM = "launched_confirm_lock";
+
+ /**
+ * Used by the choose fingerprint wizard to indicate the wizard is
+ * finished, and each activity in the wizard should finish.
+ * <p>
+ * Previously, each activity in the wizard would finish itself after
+ * starting the next activity. However, this leads to broken 'Back'
+ * behavior. So, now an activity does not finish itself until it gets this
+ * result.
+ */
+ public static final int RESULT_FINISHED = RESULT_FIRST_USER;
+
+ /**
+ * Used by the enrolling screen during setup wizard to skip over setting up fingerprint, which
+ * will be useful if the user accidentally entered this flow.
+ */
+ public static final int RESULT_SKIP = RESULT_FIRST_USER + 1;
+
+ /**
+ * Like {@link #RESULT_FINISHED} except this one indicates enrollment failed because the
+ * device was left idle. This is used to clear the credential token to require the user to
+ * re-enter their pin/pattern/password before continuing.
+ */
+ public static final int RESULT_TIMEOUT = RESULT_FIRST_USER + 2;
+
public static final int CONFIRM_REQUEST = 1;
public static final int ENROLLING = 2;
diff --git a/src/com/android/settings/biometrics/BiometricErrorDialog.java b/src/com/android/settings/biometrics/BiometricErrorDialog.java
index 5c4e891..6e5a221 100644
--- a/src/com/android/settings/biometrics/BiometricErrorDialog.java
+++ b/src/com/android/settings/biometrics/BiometricErrorDialog.java
@@ -16,8 +16,8 @@
package com.android.settings.biometrics;
-import static com.android.settings.biometrics.BiometricSettings.RESULT_FINISHED;
-import static com.android.settings.biometrics.BiometricSettings.RESULT_TIMEOUT;
+import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED;
+import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_TIMEOUT;
import android.app.Activity;
import android.app.Dialog;
diff --git a/src/com/android/settings/biometrics/BiometricSettings.java b/src/com/android/settings/biometrics/BiometricSettings.java
deleted file mode 100644
index ccb4c5e..0000000
--- a/src/com/android/settings/biometrics/BiometricSettings.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2018 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.biometrics;
-
-import com.android.settings.SubSettings;
-
-/**
- * Abstract base class for biometric settings, such as Fingerprint, Face, Iris
- */
-public abstract class BiometricSettings extends SubSettings {
- /**
- * Used by the choose fingerprint wizard to indicate the wizard is
- * finished, and each activity in the wizard should finish.
- * <p>
- * Previously, each activity in the wizard would finish itself after
- * starting the next activity. However, this leads to broken 'Back'
- * behavior. So, now an activity does not finish itself until it gets this
- * result.
- */
- protected static final int RESULT_FINISHED = RESULT_FIRST_USER;
-
- /**
- * Used by the enrolling screen during setup wizard to skip over setting up fingerprint, which
- * will be useful if the user accidentally entered this flow.
- */
- protected static final int RESULT_SKIP = RESULT_FIRST_USER + 1;
-
- /**
- * Like {@link #RESULT_FINISHED} except this one indicates enrollment failed because the
- * device was left idle. This is used to clear the credential token to require the user to
- * re-enter their pin/pattern/password before continuing.
- */
- protected static final int RESULT_TIMEOUT = RESULT_FIRST_USER + 2;
-}
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
new file mode 100644
index 0000000..4944c7f
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 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.biometrics.face;
+
+import static com.android.settings.biometrics.BiometricEnrollBase.CONFIRM_REQUEST;
+
+import android.content.Context;
+import android.hardware.face.FaceManager;
+import android.os.Bundle;
+import android.provider.SearchIndexableResource;
+import android.util.Log;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Settings screen for face authentication.
+ */
+@SearchIndexable
+public class FaceSettings extends DashboardFragment {
+
+ private static final String TAG = "FaceSettings";
+ private static final String KEY_LAUNCHED_CONFIRM = "key_launched_confirm";
+
+ private boolean mLaunchedConfirm;
+
+ public static boolean isAvailable(Context context) {
+ FaceManager manager = Utils.getFaceManagerOrNull(context);
+ return manager != null && manager.isHardwareDetected();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.FACE;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.security_settings_face;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putBoolean(KEY_LAUNCHED_CONFIRM, mLaunchedConfirm);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState != null) {
+ mLaunchedConfirm = savedInstanceState.getBoolean(KEY_LAUNCHED_CONFIRM, false);
+ }
+
+ if (!mLaunchedConfirm) {
+ ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this);
+ if (!helper.launchConfirmationActivity(CONFIRM_REQUEST,
+ getString(R.string.security_settings_face_preference_title))) {
+ Log.e(TAG, "Password not set");
+ finish();
+ }
+ }
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getSettingsLifecycle());
+ }
+
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Lifecycle lifecycle) {
+ final List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new FaceSettingsVideoPreferenceController(context));
+ controllers.add(new FaceSettingsImprovePreferenceController(context));
+ controllers.add(new FaceSettingsUnlockPreferenceController(context));
+ controllers.add(new FaceSettingsRemoveButtonPreferenceController(context));
+ controllers.add(new FaceSettingsFooterPreferenceController(context));
+ return controllers;
+ }
+
+ public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.security_settings_face;
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List<AbstractPreferenceController> createPreferenceControllers(
+ Context context) {
+ return buildPreferenceControllers(context, null /* lifecycle */);
+ }
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return isAvailable(context);
+ }
+ };
+
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
new file mode 100644
index 0000000..855b169
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 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.biometrics.face;
+
+import android.content.Context;
+import android.content.Intent;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.utils.AnnotationSpan;
+import com.android.settingslib.HelpUtils;
+import com.android.settingslib.widget.FooterPreference;
+
+import androidx.preference.Preference;
+
+/**
+ * Footer for face settings showing the help text and help link.
+ */
+public class FaceSettingsFooterPreferenceController extends BasePreferenceController {
+
+ private static final String ANNOTATION_URL = "url";
+
+ public FaceSettingsFooterPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsFooterPreferenceController(Context context) {
+ this(context, FooterPreference.KEY_FOOTER);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ final Intent helpIntent = HelpUtils.getHelpIntent(
+ mContext, mContext.getString(R.string.help_url_face), getClass().getName());
+ final AnnotationSpan.LinkInfo linkInfo =
+ new AnnotationSpan.LinkInfo(mContext, ANNOTATION_URL, helpIntent);
+ preference.setTitle(AnnotationSpan.linkify(
+ mContext.getText(R.string.security_settings_face_settings_footer), linkInfo));
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsImprovePreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsImprovePreferenceController.java
new file mode 100644
index 0000000..94b14b5
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsImprovePreferenceController.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 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.biometrics.face;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+
+import androidx.preference.Preference;
+
+/**
+ * Preference controller which allows the user to update their enrolled face.
+ */
+public class FaceSettingsImprovePreferenceController extends BasePreferenceController {
+
+ private static final String KEY = "security_settings_face_improve";
+
+ public FaceSettingsImprovePreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsImprovePreferenceController(Context context) {
+ this(context, KEY);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ return false;
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
new file mode 100644
index 0000000..b1dcce0
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 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.biometrics.face;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.BasePreferenceController;
+
+import androidx.preference.Preference;
+
+/**
+ * Controller for the remove button.
+ */
+public class FaceSettingsRemoveButtonPreferenceController extends BasePreferenceController
+ implements View.OnClickListener {
+
+ private static final String KEY = "security_settings_face_delete_faces_container";
+
+ private Button mButton;
+
+ public FaceSettingsRemoveButtonPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsRemoveButtonPreferenceController(Context context) {
+ this(context, KEY);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ mButton = ((LayoutPreference) preference)
+ .findViewById(R.id.security_settings_face_settings_remove_button);
+ mButton.setOnClickListener(this);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v == mButton) {
+
+ }
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsUnlockPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsUnlockPreferenceController.java
new file mode 100644
index 0000000..b483dc6
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsUnlockPreferenceController.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 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.biometrics.face;
+
+import static android.provider.Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import com.android.settings.core.TogglePreferenceController;
+
+import androidx.preference.Preference;
+
+/**
+ * Preference controller for Face settings page controlling the ability to unlock the phone
+ * with face.
+ */
+public class FaceSettingsUnlockPreferenceController extends TogglePreferenceController {
+
+ private static final String KEY = "security_settings_face_unlock";
+
+ private static final int ON = 1;
+ private static final int OFF = 0;
+ private static final int DEFAULT = ON; // face unlock is enabled on keyguard by default
+
+ public FaceSettingsUnlockPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsUnlockPreferenceController(Context context) {
+ this(context, KEY);
+ }
+
+ @Override
+ public boolean isChecked() {
+ if (!FaceSettings.isAvailable(mContext)) {
+ return false;
+ } else if (adminDisabled()) {
+ return false;
+ }
+ return Settings.Secure.getInt(
+ mContext.getContentResolver(), FACE_UNLOCK_KEYGUARD_ENABLED, DEFAULT) == ON;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ return Settings.Secure.putInt(mContext.getContentResolver(), FACE_UNLOCK_KEYGUARD_ENABLED,
+ isChecked ? ON : OFF);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (!FaceSettings.isAvailable(mContext)) {
+ preference.setEnabled(false);
+ } else if (adminDisabled()) {
+ preference.setEnabled(false);
+ } else {
+ preference.setEnabled(true);
+ }
+ }
+
+ private boolean adminDisabled() {
+ DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ return dpm != null &&
+ (dpm.getKeyguardDisabledFeatures(null, UserHandle.myUserId())
+ & DevicePolicyManager.KEYGUARD_DISABLE_FACE)
+ != 0;
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsVideoPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsVideoPreferenceController.java
new file mode 100644
index 0000000..6fbb9c4
--- /dev/null
+++ b/src/com/android/settings/biometrics/face/FaceSettingsVideoPreferenceController.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.biometrics.face;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class FaceSettingsVideoPreferenceController extends BasePreferenceController {
+
+ private static final String PREF_KEY_VIDEO = "security_settings_face_video";
+
+ public FaceSettingsVideoPreferenceController(Context context,
+ String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ public FaceSettingsVideoPreferenceController(Context context) {
+ this(context, PREF_KEY_VIDEO);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
index 96f22e0..9a14660 100644
--- a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java
@@ -20,6 +20,7 @@
import android.hardware.face.FaceManager;
import com.android.settings.R;
+import com.android.settings.Settings;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricStatusPreferenceController;
@@ -62,7 +63,7 @@
@Override
protected String getSettingsClassName() {
- return null;
+ return Settings.FaceSettingsActivity.class.getName();
}
@Override
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index d318fef..3309b78 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -40,8 +40,9 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.SubSettings;
import com.android.settings.Utils;
-import com.android.settings.biometrics.BiometricSettings;
+import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
@@ -66,7 +67,7 @@
/**
* Settings screen for fingerprints
*/
-public class FingerprintSettings extends BiometricSettings {
+public class FingerprintSettings extends SubSettings {
private static final String TAG = "FingerprintSettings";
@@ -75,6 +76,10 @@
public static final String ANNOTATION_URL = "url";
public static final String ANNOTATION_ADMIN_DETAILS = "admin_details";
+ private static final int RESULT_FINISHED = BiometricEnrollBase.RESULT_FINISHED;
+ private static final int RESULT_SKIP = BiometricEnrollBase.RESULT_SKIP;
+ private static final int RESULT_TIMEOUT = BiometricEnrollBase.RESULT_TIMEOUT;
+
@Override
public Intent getIntent() {
Intent modIntent = new Intent(super.getIntent());
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 219c92c..4346973 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -52,6 +52,7 @@
import com.android.settings.applications.specialaccess.vrlistener.VrListenerSettings;
import com.android.settings.backup.PrivacySettings;
import com.android.settings.backup.ToggleBackupSettingFragment;
+import com.android.settings.biometrics.face.FaceSettings;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
@@ -187,6 +188,7 @@
PowerUsageSummary.class.getName(),
AccountSyncSettings.class.getName(),
AssistGestureSettings.class.getName(),
+ FaceSettings.class.getName(),
SwipeToNotificationSettings.class.getName(),
DoubleTapPowerSettings.class.getName(),
DoubleTapScreenSettings.class.getName(),