Merge "Bug 5042999: Wi-Fi disconnect policy strings"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 56af177..1874107 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -777,22 +777,27 @@
     <!-- Title for preference that disables unlock security [CHAR LIMIT=22] -->
     <string name="unlock_set_unlock_none_title">Slide</string>
     <!-- Summary for preference that disables unlock security [CHAR LIMIT=45]-->
-    <string name="unlock_set_unlock_none_summary"></string>
+    <string name="unlock_set_unlock_none_summary">No security</string>
+
+    <!-- Title for preference that guides the user through a weak biometric lock [CHAR LIMIT=22] -->
+    <string name="unlock_set_unlock_biometric_weak_title">FacePass</string>
+    <!-- Summary for preference that disables unlock security [CHAR LIMIT=45]-->
+    <string name="unlock_set_unlock_biometric_weak_summary">Low security, experimental</string>
 
     <!-- Title for preference that guides the user through creating an unlock pattern [CHAR LIMIT=22]-->
     <string name="unlock_set_unlock_pattern_title">Pattern</string>
     <!-- Summary for preference that guides the user through creating an unlock pattern [CHAR LIMIT=45] -->
-    <string name="unlock_set_unlock_pattern_summary"></string>
+    <string name="unlock_set_unlock_pattern_summary">Medium security</string>
 
     <!-- Title for preference that guides the user through creating an unlock PIN (Personal Identification Number) [CHAR LIMIT=22] -->
     <string name="unlock_set_unlock_pin_title">PIN</string>
     <!-- Summary for preference that guides the user through creating an unlock PIN (Personal Identification Number) [CHAR LIMIT=45] -->
-    <string name="unlock_set_unlock_pin_summary"></string>
+    <string name="unlock_set_unlock_pin_summary">Medium to high security</string>
 
     <!-- Title for preference that guides the user through creating an unlock password [CHAR LIMIT=22] -->
     <string name="unlock_set_unlock_password_title">Password</string>
     <!-- Title for preference that guides the user through creating an unlock password [CHAR LIMIT=45] -->
-    <string name="unlock_set_unlock_password_summary"></string>
+    <string name="unlock_set_unlock_password_summary">High security</string>
 
     <!-- Summary for preference that has been disabled by because of the DevicePolicyAdmin, or because device encryption is enabled, or because there are credentials in the credential storage [CHAR LIMIT=50] -->
     <string name="unlock_set_unlock_disabled_summary">Disabled by administrator, encryption policy, or credential storage</string>
@@ -801,6 +806,8 @@
     <string name="unlock_set_unlock_mode_off">None</string>
     <!-- Summary for "Configure lockscreen" when security is disabled [CHAR LIMIT=45] -->
     <string name="unlock_set_unlock_mode_none">Slide</string>
+    <!-- Summary for "Configure lockscreen" when security biometric weak is enabled [CHAR LIMIT=45] -->
+    <string name="unlock_set_unlock_mode_biometric_weak">FacePass</string>
     <!-- Summary for "Configure lockscreen" when security pattern is enabled [CHAR LIMIT=45] -->
     <string name="unlock_set_unlock_mode_pattern">Secured with pattern</string>
     <!-- Summary for "Configure lockscreen" when security PIN is enabled [CHAR LIMIT=45] -->
diff --git a/res/xml/security_settings_biometric_weak.xml b/res/xml/security_settings_biometric_weak.xml
new file mode 100644
index 0000000..42af769
--- /dev/null
+++ b/res/xml/security_settings_biometric_weak.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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">
+
+    <PreferenceCategory
+        android:key="security_category"
+        android:title="@string/lock_settings_title">
+
+        <PreferenceScreen
+            android:key="unlock_set_or_change"
+            android:title="@string/unlock_set_unlock_launch_picker_title"
+            android:summary="@string/unlock_set_unlock_mode_biometric_weak"
+            android:persistent="false"/>
+
+        <ListPreference
+            android:key="lock_after_timeout"
+            android:title="@string/lock_after_timeout"
+            android:summary="@string/lock_after_timeout_summary"
+            android:entries="@array/lock_after_timeout_entries"
+            android:entryValues="@array/lock_after_timeout_values"
+            android:persistent="false"/>
+
+        <PreferenceScreen
+            android:fragment="com.android.settings.OwnerInfoSettings"
+            android:key="owner_info_settings"
+            android:title="@string/owner_info_settings_title"
+            android:summary="@string/owner_info_settings_summary"/>
+
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/security_settings_picker.xml b/res/xml/security_settings_picker.xml
index 04258df..c220214 100644
--- a/res/xml/security_settings_picker.xml
+++ b/res/xml/security_settings_picker.xml
@@ -33,6 +33,12 @@
             android:persistent="false"/>
 
         <PreferenceScreen
+            android:key="unlock_set_biometric_weak"
+            android:title="@string/unlock_set_unlock_biometric_weak_title"
+            android:summary="@string/unlock_set_unlock_biometric_weak_summary"
+            android:persistent="false"/>
+
+        <PreferenceScreen
             android:key="unlock_set_pattern"
             android:title="@string/unlock_set_unlock_pattern_title"
             android:summary="@string/unlock_set_unlock_pattern_summary"
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index b1bc856..5e44df3 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -17,10 +17,12 @@
 package com.android.settings;
 
 import android.app.Activity;
+import android.app.PendingIntent;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.SystemProperties;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceCategory;
@@ -43,6 +45,7 @@
         private static final int MIN_PASSWORD_LENGTH = 4;
         private static final String KEY_UNLOCK_SET_OFF = "unlock_set_off";
         private static final String KEY_UNLOCK_SET_NONE = "unlock_set_none";
+        private static final String KEY_UNLOCK_SET_BIOMETRIC_WEAK = "unlock_set_biometric_weak";
         private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin";
         private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
         private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
@@ -91,7 +94,10 @@
             } else if (KEY_UNLOCK_SET_NONE.equals(key)) {
                 updateUnlockMethodAndFinish(
                         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, false);
-            } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
+            } else if (KEY_UNLOCK_SET_BIOMETRIC_WEAK.equals(key)) {
+                updateUnlockMethodAndFinish(
+                        DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK, false);
+            }else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
                 updateUnlockMethodAndFinish(
                         DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false);
             } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
@@ -126,11 +132,11 @@
         }
 
         private void updatePreferencesOrFinish() {
-            int quality = getActivity().getIntent()
-                    .getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
+            Intent intent = getActivity().getIntent();
+            int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
             if (quality == -1) {
                 // If caller didn't specify password quality, show UI and allow the user to choose.
-                quality = getActivity().getIntent().getIntExtra(MINIMUM_QUALITY_KEY, -1);
+                quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
                 quality = upgradeQuality(quality);
                 final PreferenceScreen prefScreen = getPreferenceScreen();
                 if (prefScreen != null) {
@@ -197,15 +203,23 @@
                     getPreferenceScreen().findPreference("security_picker_category");
             final PreferenceCategory cat = (PreferenceCategory) picker;
             final int preferenceCount = cat.getPreferenceCount();
-            for (int i = 0; i < preferenceCount; i++) {
+            final boolean onlyShowFallback = getActivity().getIntent()
+                    .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false);
+            final boolean weakBiometricAvailable = isBiometricSensorAvailable(
+                    DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
+            for (int i = preferenceCount-1; i >= 0; --i) {
                 Preference pref = cat.getPreference(i);
                 if (pref instanceof PreferenceScreen) {
                     final String key = ((PreferenceScreen) pref).getKey();
                     boolean enabled = true;
+                    boolean visible = true;
                     if (KEY_UNLOCK_SET_OFF.equals(key)) {
                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
                     } else if (KEY_UNLOCK_SET_NONE.equals(key)) {
                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+                    } else if (KEY_UNLOCK_SET_BIOMETRIC_WEAK.equals(key)) {
+                        enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+                        visible = weakBiometricAvailable; // If not available, then don't show it.
                     } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
                     } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
@@ -213,7 +227,9 @@
                     } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
                     }
-                    if (!enabled) {
+                    if (!visible || (onlyShowFallback && !allowedForFallback(key))) {
+                        cat.removePreference(pref);
+                    } else if (!enabled) {
                         pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
                         pref.setEnabled(false);
                     }
@@ -222,6 +238,34 @@
         }
 
         /**
+         * Check whether the key is allowed for fallback (e.g. bio sensor). Returns true if it's
+         * supported as a backup.
+         *
+         * @param key
+         * @return true if allowed
+         */
+        private boolean allowedForFallback(String key) {
+            return KEY_UNLOCK_SET_PATTERN.equals(key) || KEY_UNLOCK_SET_PIN.equals(key);
+        }
+
+        private boolean isBiometricSensorAvailable(int quality) {
+            return SystemProperties.getBoolean("ro.lockscreen.facelock_enabled", false);
+        }
+
+        private Intent getBiometricSensorIntent(int quality) {
+            Intent fallBackIntent = new Intent().setClass(getActivity(), ChooseLockGeneric.class);
+            fallBackIntent.putExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, true);
+            fallBackIntent.putExtra(CONFIRM_CREDENTIALS, false);
+            fallBackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+            Intent intent = new Intent().setClassName("com.android.facelock",
+                    "com.android.facelock.SetupFaceLock");
+            PendingIntent pending = PendingIntent.getActivity(getActivity(), 0, fallBackIntent, 0);
+            intent.putExtra("PendingIntent", pending);
+            return intent;
+        }
+
+        /**
          * Invokes an activity to change the user's pattern, password or PIN based on given quality
          * and minimum quality specified by DevicePolicyManager. If quality is
          * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}, password is cleared.
@@ -236,6 +280,9 @@
                 throw new IllegalStateException("Tried to update password without confirming it");
             }
 
+            final boolean isFallback = getActivity().getIntent()
+                .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false);
+
             quality = upgradeQuality(quality);
             if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
                 int minLength = mDPM.getPasswordMinimumLength(null);
@@ -249,6 +296,8 @@
                 intent.putExtra(ChooseLockPassword.PASSWORD_MAX_KEY, maxLength);
                 intent.putExtra(CONFIRM_CREDENTIALS, false);
                 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+                intent.putExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
+                        isFallback);
                 startActivity(intent);
             } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
                 boolean showTutorial = !mChooseLockSettingsHelper.utils().isPatternEverChosen();
@@ -259,6 +308,11 @@
                 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
                 intent.putExtra("key_lock_method", "pattern");
                 intent.putExtra(CONFIRM_CREDENTIALS, false);
+                intent.putExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
+                        isFallback);
+                startActivity(intent);
+            } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
+                Intent intent = getBiometricSensorIntent(quality);
                 startActivity(intent);
             } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                 mChooseLockSettingsHelper.utils().clearLock();
diff --git a/src/com/android/settings/ChooseLockPassword.java b/src/com/android/settings/ChooseLockPassword.java
index 96255eb..c201d15 100644
--- a/src/com/android/settings/ChooseLockPassword.java
+++ b/src/com/android/settings/ChooseLockPassword.java
@@ -368,7 +368,9 @@
             } else if (mUiStage == Stage.NeedToConfirm) {
                 if (mFirstPin.equals(pin)) {
                     mLockPatternUtils.clearLock();
-                    mLockPatternUtils.saveLockPassword(pin, mRequestedQuality);
+                    final boolean isFallback = getActivity().getIntent().getBooleanExtra(
+                            LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false);
+                    mLockPatternUtils.saveLockPassword(pin, mRequestedQuality, isFallback);
                     getActivity().finish();
                 } else {
                     updateStage(Stage.ConfirmWrong);
diff --git a/src/com/android/settings/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java
index 9a34f2f..180eee1 100644
--- a/src/com/android/settings/ChooseLockPattern.java
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -507,7 +507,9 @@
             LockPatternUtils utils = mChooseLockSettingsHelper.utils();
             final boolean lockVirgin = !utils.isPatternEverChosen();
 
-            utils.saveLockPattern(mChosenPattern);
+            final boolean isFallback = getActivity().getIntent()
+                .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false);
+            utils.saveLockPattern(mChosenPattern, isFallback);
             utils.setLockPatternEnabled(true);
 
             if (lockVirgin) {
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 3813ecd..5b8035d 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -106,6 +106,8 @@
             } else {
                 resid = R.xml.security_settings_chooser;
             }
+        } else if (mLockPatternUtils.usingBiometricWeak()) {
+            resid = R.xml.security_settings_biometric_weak;
         } else {
             switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
                 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
@@ -120,6 +122,7 @@
                     resid = R.xml.security_settings_password;
                     break;
             }
+            // TODO: enable facepass options
         }
         addPreferencesFromResource(resid);