DO NOT MERGE Provide fingerprint options for SET_NEW_PASSWORD intent
Cherry-pick from ag/1444396 1) Added a trampoline activity to display SET_NEW_PASSWORD intent. 2) On devices that have fingerprint sensor and have no enrolled fingerprint, ChooseLockGeneric handles the SET_NEW_PASSWORD intent by providing fingerprint + {PIN/PATTERN/PASSWORD} and skip fingerprint options. Test: See below 1) Auto make RunSettingsRoboTests 2) Manual a) Fingerprint + pattern i) $ adb shell am start -a android.app.action.SET_NEW_PASSWORD ii) Click Pixel Imprint + Pattern. iii) Set a pattern lock. iv) Can enroll a fingerprint. b) Pattern i) $ adb shell am start -a android.app.action.SET_NEW_PASSWORD ii) Click Continue without Pixel Imprint iii) A list of unlock options, without fingerprint option, is shown. vi) Select and enroll a pattern lock c) Has an existing password i) $ adb shell am start -a android.app.action.SET_NEW_PASSWORD ii) Setting app asks for password input. iii) Enter password and click "Continue without Pixel imprint". vi) No password is asked. A list of unlock options, without fingerprint option, is shown. v) Select and enroll a pattern lock d) Work profile i) Create a work profile ii) adb shell am start --user x -a android.app.action.SET_NEW_PASSWORD. X is the work profile user id. iii) Click Pixel Imprint + Pattern. iv) Set a pattern lock. v) Can enroll a fingerprint. Bug: 23017051 Change-Id: I6384bbffb72a5d3a83972da7474532746e4d06b9
This commit is contained in:
@@ -1713,6 +1713,11 @@
|
|||||||
|
|
||||||
<activity android:name="ChooseLockGeneric"
|
<activity android:name="ChooseLockGeneric"
|
||||||
android:label="@string/lockpassword_choose_lock_generic_header"
|
android:label="@string/lockpassword_choose_lock_generic_header"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity android:name=".password.SetNewPasswordActivity"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay"
|
||||||
android:excludeFromRecents="true" >
|
android:excludeFromRecents="true" >
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.app.action.SET_NEW_PASSWORD" />
|
<action android:name="android.app.action.SET_NEW_PASSWORD" />
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/fingerprint_header_description"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
@@ -22,4 +23,4 @@
|
|||||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
android:text="@string/lock_settings_picker_fingerprint_message"
|
android:text="@string/lock_settings_picker_fingerprint_message"
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
|
style="@style/FingerprintHeaderStyle" />
|
||||||
|
@@ -1083,6 +1083,12 @@
|
|||||||
<!-- Title for preference that guides the user through creating a backup unlock password for fingerprint [CHAR LIMIT=45]-->
|
<!-- Title for preference that guides the user through creating a backup unlock password for fingerprint [CHAR LIMIT=45]-->
|
||||||
<string name="fingerprint_unlock_set_unlock_password">Fingerprint + Password</string>
|
<string name="fingerprint_unlock_set_unlock_password">Fingerprint + Password</string>
|
||||||
|
|
||||||
|
<!-- Title for preference that guides the user to skip fingerprint setup [CHAR LIMIT=60]-->
|
||||||
|
<string name="fingerprint_unlock_skip_fingerprint">Continue without fingerprint</string>
|
||||||
|
|
||||||
|
<!-- Message shown in screen lock picker while setting up the new screen lock with fingerprint option. [CHAR LIMIT=NONE]-->
|
||||||
|
<string name="fingerprint_unlock_title">You can unlock your phone using your fingerprint. For security, this option requires a backup screen lock.</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] -->
|
<!-- 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>
|
<string name="unlock_set_unlock_disabled_summary">Disabled by administrator, encryption policy, or credential storage</string>
|
||||||
|
|
||||||
|
@@ -435,4 +435,10 @@
|
|||||||
<item name="android:paddingEnd">56dp</item>
|
<item name="android:paddingEnd">56dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="FingerprintHeaderStyle" parent="android:style/TextAppearance.Material.Subhead">
|
||||||
|
<item name="android:paddingTop">16dp</item>
|
||||||
|
<item name="android:textColor">@color/primary_dark_material_light</item>
|
||||||
|
<item name="android:lineSpacingMultiplier">1.2</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -47,4 +47,9 @@
|
|||||||
android:key="unlock_set_managed"
|
android:key="unlock_set_managed"
|
||||||
android:persistent="false"/>
|
android:persistent="false"/>
|
||||||
|
|
||||||
|
<com.android.settingslib.RestrictedPreference
|
||||||
|
android:key="unlock_skip_fingerprint"
|
||||||
|
android:title="@string/fingerprint_unlock_skip_fingerprint"
|
||||||
|
android:persistent="false"/>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@@ -16,6 +16,11 @@
|
|||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings;
|
||||||
|
|
||||||
|
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD;
|
||||||
|
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
|
||||||
|
import static com.android.settings.ChooseLockPassword.ChooseLockPasswordFragment.RESULT_FINISHED;
|
||||||
|
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
|
||||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
@@ -42,16 +47,17 @@ import android.text.TextUtils;
|
|||||||
import android.util.EventLog;
|
import android.util.EventLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
import com.android.settings.fingerprint.FingerprintEnrollBase;
|
||||||
|
import com.android.settings.fingerprint.FingerprintEnrollFindSensor;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
import com.android.settingslib.RestrictedPreference;
|
import com.android.settingslib.RestrictedPreference;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
|
||||||
|
|
||||||
public class ChooseLockGeneric extends SettingsActivity {
|
public class ChooseLockGeneric extends SettingsActivity {
|
||||||
public static final String CONFIRM_CREDENTIALS = "confirm_credentials";
|
public static final String CONFIRM_CREDENTIALS = "confirm_credentials";
|
||||||
|
|
||||||
@@ -61,8 +67,8 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
|
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
|
||||||
|
|
||||||
String action = modIntent.getAction();
|
String action = modIntent.getAction();
|
||||||
if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD.equals(action)
|
if (ACTION_SET_NEW_PASSWORD.equals(action)
|
||||||
|| DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
|
|| ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
|
||||||
modIntent.putExtra(EXTRA_HIDE_DRAWER, true);
|
modIntent.putExtra(EXTRA_HIDE_DRAWER, true);
|
||||||
}
|
}
|
||||||
return modIntent;
|
return modIntent;
|
||||||
@@ -90,6 +96,7 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
|
private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
|
||||||
private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
|
private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
|
||||||
private static final String KEY_UNLOCK_SET_MANAGED = "unlock_set_managed";
|
private static final String KEY_UNLOCK_SET_MANAGED = "unlock_set_managed";
|
||||||
|
private static final String KEY_SKIP_FINGERPRINT = "unlock_skip_fingerprint";
|
||||||
private static final String PASSWORD_CONFIRMED = "password_confirmed";
|
private static final String PASSWORD_CONFIRMED = "password_confirmed";
|
||||||
private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
|
private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
|
||||||
public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
|
public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
|
||||||
@@ -101,6 +108,8 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
private static final int CONFIRM_EXISTING_REQUEST = 100;
|
private static final int CONFIRM_EXISTING_REQUEST = 100;
|
||||||
private static final int ENABLE_ENCRYPTION_REQUEST = 101;
|
private static final int ENABLE_ENCRYPTION_REQUEST = 101;
|
||||||
private static final int CHOOSE_LOCK_REQUEST = 102;
|
private static final int CHOOSE_LOCK_REQUEST = 102;
|
||||||
|
private static final int CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST = 103;
|
||||||
|
private static final int SKIP_FINGERPRINT_REQUEST = 104;
|
||||||
|
|
||||||
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
|
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
|
||||||
private DevicePolicyManager mDPM;
|
private DevicePolicyManager mDPM;
|
||||||
@@ -119,6 +128,7 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
private int mUserId;
|
private int mUserId;
|
||||||
private boolean mHideDrawer = false;
|
private boolean mHideDrawer = false;
|
||||||
private ManagedLockPasswordProvider mManagedPasswordProvider;
|
private ManagedLockPasswordProvider mManagedPasswordProvider;
|
||||||
|
private boolean mIsSetNewPassword = false;
|
||||||
|
|
||||||
protected boolean mForFingerprint = false;
|
protected boolean mForFingerprint = false;
|
||||||
|
|
||||||
@@ -131,12 +141,15 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
String chooseLockAction = getActivity().getIntent().getAction();
|
||||||
mFingerprintManager =
|
mFingerprintManager =
|
||||||
(FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
|
(FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
|
||||||
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
|
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
mKeyStore = KeyStore.getInstance();
|
mKeyStore = KeyStore.getInstance();
|
||||||
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
|
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
|
||||||
mLockPatternUtils = new LockPatternUtils(getActivity());
|
mLockPatternUtils = new LockPatternUtils(getActivity());
|
||||||
|
mIsSetNewPassword = ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction)
|
||||||
|
|| ACTION_SET_NEW_PASSWORD.equals(chooseLockAction);
|
||||||
|
|
||||||
// Defaults to needing to confirm credentials
|
// Defaults to needing to confirm credentials
|
||||||
final boolean confirmCredentials = getActivity().getIntent()
|
final boolean confirmCredentials = getActivity().getIntent()
|
||||||
@@ -154,6 +167,16 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
|
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
|
||||||
mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean(
|
mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean(
|
||||||
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT);
|
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT);
|
||||||
|
if (mIsSetNewPassword) {
|
||||||
|
// In ACTION_SET_NEW_PARENT_PROFILE_PASSWORD or ACTION_SET_NEW_PASSWORD, the user
|
||||||
|
// will be asked to confirm the password if one has been set.
|
||||||
|
// On fingerprint supported device, fingerprint options are represented in the
|
||||||
|
// options. If the user chooses to skip fingerprint setup, ChooseLockGeneric is
|
||||||
|
// relaunched to only show options without fingerprint. In this case, we shouldn't
|
||||||
|
// ask the user to confirm the password again.
|
||||||
|
mPasswordConfirmed = getActivity().getIntent().getBooleanExtra(
|
||||||
|
PASSWORD_CONFIRMED, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
|
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
|
||||||
@@ -168,9 +191,8 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
UserManager.get(getActivity()),
|
UserManager.get(getActivity()),
|
||||||
null,
|
null,
|
||||||
getActivity().getIntent().getExtras()).getIdentifier();
|
getActivity().getIntent().getExtras()).getIdentifier();
|
||||||
if (DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(
|
if (ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction)
|
||||||
getActivity().getIntent().getAction()) ||
|
|| !mLockPatternUtils.isSeparateProfileChallengeAllowed(targetUser)) {
|
||||||
!mLockPatternUtils.isSeparateProfileChallengeAllowed(targetUser)) {
|
|
||||||
// Always use parent if explicitely requested or if profile challenge is not
|
// Always use parent if explicitely requested or if profile challenge is not
|
||||||
// supported
|
// supported
|
||||||
Bundle arguments = getArguments();
|
Bundle arguments = getArguments();
|
||||||
@@ -180,8 +202,7 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
mUserId = targetUser;
|
mUserId = targetUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD
|
if (ACTION_SET_NEW_PASSWORD.equals(chooseLockAction)
|
||||||
.equals(getActivity().getIntent().getAction())
|
|
||||||
&& Utils.isManagedProfile(UserManager.get(getActivity()), mUserId)
|
&& Utils.isManagedProfile(UserManager.get(getActivity()), mUserId)
|
||||||
&& mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
|
&& mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
|
||||||
getActivity().setTitle(R.string.lock_settings_picker_title_profile);
|
getActivity().setTitle(R.string.lock_settings_picker_title_profile);
|
||||||
@@ -216,6 +237,10 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
protected void addHeaderView() {
|
protected void addHeaderView() {
|
||||||
if (mForFingerprint) {
|
if (mForFingerprint) {
|
||||||
setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
|
setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
|
||||||
|
if (mIsSetNewPassword) {
|
||||||
|
((TextView) getHeaderView().findViewById(R.id.fingerprint_header_description))
|
||||||
|
.setText(R.string.fingerprint_unlock_title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +253,12 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
// unlock method to an insecure one
|
// unlock method to an insecure one
|
||||||
showFactoryResetProtectionWarningDialog(key);
|
showFactoryResetProtectionWarningDialog(key);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (KEY_SKIP_FINGERPRINT.equals(key)) {
|
||||||
|
Intent chooseLockGenericIntent = new Intent(getActivity(), ChooseLockGeneric.class);
|
||||||
|
chooseLockGenericIntent.setAction(getIntent().getAction());
|
||||||
|
chooseLockGenericIntent.putExtra(PASSWORD_CONFIRMED, mPasswordConfirmed);
|
||||||
|
startActivityForResult(chooseLockGenericIntent, SKIP_FINGERPRINT_REQUEST);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return setUnlockMethod(key);
|
return setUnlockMethod(key);
|
||||||
}
|
}
|
||||||
@@ -302,6 +333,20 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
getActivity().setResult(resultCode, data);
|
getActivity().setResult(resultCode, data);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
} else if (requestCode == CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
|
||||||
|
&& resultCode == FingerprintEnrollBase.RESULT_FINISHED) {
|
||||||
|
Intent intent = new Intent(getActivity(), FingerprintEnrollFindSensor.class);
|
||||||
|
if (data != null) {
|
||||||
|
intent.putExtras(data.getExtras());
|
||||||
|
}
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
} else if (requestCode == SKIP_FINGERPRINT_REQUEST) {
|
||||||
|
if (resultCode != RESULT_CANCELED) {
|
||||||
|
getActivity().setResult(
|
||||||
|
resultCode == RESULT_FINISHED ? RESULT_OK : resultCode, data);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
getActivity().setResult(Activity.RESULT_CANCELED);
|
getActivity().setResult(Activity.RESULT_CANCELED);
|
||||||
finish();
|
finish();
|
||||||
@@ -375,6 +420,10 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
} else {
|
} else {
|
||||||
removePreference(KEY_UNLOCK_SET_MANAGED);
|
removePreference(KEY_UNLOCK_SET_MANAGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(mForFingerprint && mIsSetNewPassword)) {
|
||||||
|
removePreference(KEY_SKIP_FINGERPRINT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCurrentPreference() {
|
private void updateCurrentPreference() {
|
||||||
@@ -607,7 +656,10 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
quality = upgradeQuality(quality);
|
quality = upgradeQuality(quality);
|
||||||
Intent intent = getIntentForUnlockMethod(quality, disabled);
|
Intent intent = getIntentForUnlockMethod(quality, disabled);
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
|
startActivityForResult(intent,
|
||||||
|
mIsSetNewPassword && mHasChallenge
|
||||||
|
? CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
|
||||||
|
: CHOOSE_LOCK_REQUEST);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,8 +667,8 @@ public class ChooseLockGeneric extends SettingsActivity {
|
|||||||
mLockPatternUtils.setSeparateProfileChallengeEnabled(mUserId, true, mUserPassword);
|
mLockPatternUtils.setSeparateProfileChallengeEnabled(mUserId, true, mUserPassword);
|
||||||
mChooseLockSettingsHelper.utils().clearLock(mUserId);
|
mChooseLockSettingsHelper.utils().clearLock(mUserId);
|
||||||
mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId);
|
mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId);
|
||||||
removeAllFingerprintForUserAndFinish(mUserId);
|
|
||||||
getActivity().setResult(Activity.RESULT_OK);
|
getActivity().setResult(Activity.RESULT_OK);
|
||||||
|
removeAllFingerprintForUserAndFinish(mUserId);
|
||||||
} else {
|
} else {
|
||||||
removeAllFingerprintForUserAndFinish(mUserId);
|
removeAllFingerprintForUserAndFinish(mUserId);
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,7 @@ import com.android.setupwizardlib.GlifLayout;
|
|||||||
*/
|
*/
|
||||||
public abstract class FingerprintEnrollBase extends InstrumentedActivity
|
public abstract class FingerprintEnrollBase extends InstrumentedActivity
|
||||||
implements View.OnClickListener {
|
implements View.OnClickListener {
|
||||||
static final int RESULT_FINISHED = FingerprintSettings.RESULT_FINISHED;
|
public static final int RESULT_FINISHED = FingerprintSettings.RESULT_FINISHED;
|
||||||
static final int RESULT_SKIP = FingerprintSettings.RESULT_SKIP;
|
static final int RESULT_SKIP = FingerprintSettings.RESULT_SKIP;
|
||||||
static final int RESULT_TIMEOUT = FingerprintSettings.RESULT_TIMEOUT;
|
static final int RESULT_TIMEOUT = FingerprintSettings.RESULT_TIMEOUT;
|
||||||
|
|
||||||
|
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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.password;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.android.settings.ChooseLockGeneric;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trampolines {@link DevicePolicyManager#ACTION_SET_NEW_PASSWORD} and
|
||||||
|
* {@link DevicePolicyManager#ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} intent to the appropriate UI
|
||||||
|
* activity for handling set new password.
|
||||||
|
*/
|
||||||
|
public class SetNewPasswordActivity extends Activity implements SetNewPasswordController.Ui {
|
||||||
|
private String mNewPasswordAction;
|
||||||
|
private SetNewPasswordController mSetNewPasswordController;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedState) {
|
||||||
|
super.onCreate(savedState);
|
||||||
|
|
||||||
|
mNewPasswordAction = getIntent().getAction();
|
||||||
|
mSetNewPasswordController = new SetNewPasswordController(this, this);
|
||||||
|
mSetNewPasswordController.dispatchSetNewPasswordIntent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void launchChooseLock(@Nullable Bundle chooseLockFingerprintExtras) {
|
||||||
|
Intent intent = new Intent(this, ChooseLockGeneric.class)
|
||||||
|
.setAction(mNewPasswordAction);
|
||||||
|
if (chooseLockFingerprintExtras != null) {
|
||||||
|
intent.putExtras(chooseLockFingerprintExtras);
|
||||||
|
}
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
114
src/com/android/settings/password/SetNewPasswordController.java
Normal file
114
src/com/android/settings/password/SetNewPasswordController.java
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* 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.password;
|
||||||
|
|
||||||
|
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.hardware.fingerprint.FingerprintManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.settings.ChooseLockGeneric;
|
||||||
|
import com.android.settings.ChooseLockSettingsHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Business logic for {@link SetNewPasswordActivity}.
|
||||||
|
*
|
||||||
|
* <p>On devices that supports fingerprint, this controller directs the user to configure
|
||||||
|
* fingerprint + a backup password if the device admin allows fingerprint for keyguard and
|
||||||
|
* the user has never configured a fingerprint before.
|
||||||
|
*/
|
||||||
|
final class SetNewPasswordController {
|
||||||
|
|
||||||
|
interface Ui {
|
||||||
|
/** Starts the {@link ChooseLockGeneric} activity with the given extras. */
|
||||||
|
void launchChooseLock(@Nullable Bundle chooseLockFingerprintExtras);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int mCurrentUserId;
|
||||||
|
private final PackageManager mPackageManager;
|
||||||
|
@Nullable private final FingerprintManager mFingerprintManager;
|
||||||
|
private final DevicePolicyManager mDevicePolicyManager;
|
||||||
|
private final Ui mUi;
|
||||||
|
|
||||||
|
public SetNewPasswordController(Context context, Ui ui) {
|
||||||
|
this(context.getUserId(),
|
||||||
|
context.getPackageManager(),
|
||||||
|
(FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE),
|
||||||
|
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE),
|
||||||
|
ui);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
SetNewPasswordController(
|
||||||
|
int currentUserId,
|
||||||
|
PackageManager packageManager,
|
||||||
|
FingerprintManager fingerprintManager,
|
||||||
|
DevicePolicyManager devicePolicyManager,
|
||||||
|
Ui ui) {
|
||||||
|
mCurrentUserId = currentUserId;
|
||||||
|
mPackageManager = checkNotNull(packageManager);
|
||||||
|
mFingerprintManager = fingerprintManager;
|
||||||
|
mDevicePolicyManager = checkNotNull(devicePolicyManager);
|
||||||
|
mUi = checkNotNull(ui);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches the set new password intent to the correct activity that handles it.
|
||||||
|
*/
|
||||||
|
public void dispatchSetNewPasswordIntent() {
|
||||||
|
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
|
||||||
|
&& mFingerprintManager != null
|
||||||
|
&& mFingerprintManager.isHardwareDetected()
|
||||||
|
&& !mFingerprintManager.hasEnrolledFingerprints()
|
||||||
|
&& !isFingerprintDisabledByAdmin()) {
|
||||||
|
mUi.launchChooseLock(getFingerprintChooseLockExtras());
|
||||||
|
} else {
|
||||||
|
mUi.launchChooseLock(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bundle getFingerprintChooseLockExtras() {
|
||||||
|
Bundle chooseLockExtras = new Bundle();
|
||||||
|
if (mFingerprintManager != null) {
|
||||||
|
long challenge = mFingerprintManager.preEnroll();
|
||||||
|
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
|
||||||
|
chooseLockExtras.putBoolean(
|
||||||
|
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
|
||||||
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
|
||||||
|
chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
|
||||||
|
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
|
||||||
|
if (mCurrentUserId != UserHandle.USER_NULL) {
|
||||||
|
chooseLockExtras.putInt(Intent.EXTRA_USER_ID, mCurrentUserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chooseLockExtras;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFingerprintDisabledByAdmin() {
|
||||||
|
int disabledFeatures = mDevicePolicyManager.getKeyguardDisabledFeatures(
|
||||||
|
null, mCurrentUserId);
|
||||||
|
return (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* 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.password;
|
||||||
|
|
||||||
|
import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
|
||||||
|
import static com.android.settings.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS;
|
||||||
|
import static com.android.settings.ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY;
|
||||||
|
import static com.android.settings.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE;
|
||||||
|
import static com.android.settings.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT;
|
||||||
|
import static com.android.settings.ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.hardware.fingerprint.FingerprintManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link SetNewPasswordController}.
|
||||||
|
*/
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public final class SetNewPasswordControllerTest {
|
||||||
|
private static final int CURRENT_UID = 101;
|
||||||
|
private static final long FINGERPRINT_CHALLENGE = -9876512313131L;
|
||||||
|
|
||||||
|
@Mock PackageManager mPackageManager;
|
||||||
|
@Mock FingerprintManager mFingerprintManager;
|
||||||
|
@Mock DevicePolicyManager mDevicePolicyManager;
|
||||||
|
|
||||||
|
@Mock private SetNewPasswordController.Ui mUi;
|
||||||
|
private SetNewPasswordController mSetNewPasswordController;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
mSetNewPasswordController = new SetNewPasswordController(
|
||||||
|
CURRENT_UID, mPackageManager, mFingerprintManager, mDevicePolicyManager, mUi);
|
||||||
|
|
||||||
|
when(mFingerprintManager.preEnroll()).thenReturn(FINGERPRINT_CHALLENGE);
|
||||||
|
when(mPackageManager.hasSystemFeature(eq(FEATURE_FINGERPRINT))).thenReturn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchChooseLockWithFingerprint() {
|
||||||
|
// GIVEN the device supports fingerprint.
|
||||||
|
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||||
|
// GIVEN there are no enrolled fingerprints.
|
||||||
|
when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false);
|
||||||
|
// GIVEN DPC does not disallow fingerprint for keyguard usage.
|
||||||
|
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
|
||||||
|
.thenReturn(0);
|
||||||
|
|
||||||
|
// WHEN the controller dispatches a set new password intent.
|
||||||
|
mSetNewPasswordController.dispatchSetNewPasswordIntent();
|
||||||
|
|
||||||
|
// THEN the choose lock activity is launched with fingerprint extras.
|
||||||
|
ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||||
|
verify(mUi).launchChooseLock(bundleArgumentCaptor.capture());
|
||||||
|
// THEN the extras have all values for fingerprint setup.
|
||||||
|
compareFingerprintExtras(bundleArgumentCaptor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchChooseLockWithoutFingerprint_noFingerprintFeature() {
|
||||||
|
// GIVEN the device does NOT support fingerprint feature.
|
||||||
|
when(mPackageManager.hasSystemFeature(eq(FEATURE_FINGERPRINT))).thenReturn(false);
|
||||||
|
|
||||||
|
// WHEN the controller dispatches a set new password intent.
|
||||||
|
mSetNewPasswordController.dispatchSetNewPasswordIntent();
|
||||||
|
|
||||||
|
// THEN the choose lock activity is launched without fingerprint extras.
|
||||||
|
verify(mUi).launchChooseLock(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchChooseLockWithoutFingerprint_noFingerprintSensor() {
|
||||||
|
// GIVEN the device does NOT support fingerprint.
|
||||||
|
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
|
||||||
|
// GIVEN there are no enrolled fingerprints.
|
||||||
|
when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(false);
|
||||||
|
// GIVEN DPC does not disallow fingerprint for keyguard usage.
|
||||||
|
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
|
||||||
|
.thenReturn(0);
|
||||||
|
|
||||||
|
// WHEN the controller dispatches a set new password intent.
|
||||||
|
mSetNewPasswordController.dispatchSetNewPasswordIntent();
|
||||||
|
|
||||||
|
// THEN the choose lock activity is launched without fingerprint extras.
|
||||||
|
verify(mUi).launchChooseLock(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchChooseLockWithoutFingerprint_hasFingerprintEnrolled() {
|
||||||
|
// GIVEN the device supports fingerprint.
|
||||||
|
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||||
|
// GIVEN there are no enrolled fingerprints.
|
||||||
|
when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(true);
|
||||||
|
// GIVEN DPC does not disallow fingerprint for keyguard usage.
|
||||||
|
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
|
||||||
|
.thenReturn(0);
|
||||||
|
|
||||||
|
// WHEN the controller dispatches a set new password intent.
|
||||||
|
mSetNewPasswordController.dispatchSetNewPasswordIntent();
|
||||||
|
|
||||||
|
// THEN the choose lock activity is launched without fingerprint extras.
|
||||||
|
verify(mUi).launchChooseLock(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchChooseLockWithoutFingerprint_deviceAdminDisallowFingerprintForKeyguard() {
|
||||||
|
// GIVEN the device supports fingerprint.
|
||||||
|
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||||
|
// GIVEN there is an enrolled fingerprint.
|
||||||
|
when(mFingerprintManager.hasEnrolledFingerprints()).thenReturn(true);
|
||||||
|
// GIVEN DPC disallows fingerprint for keyguard usage.
|
||||||
|
when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class)))
|
||||||
|
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
|
||||||
|
|
||||||
|
// WHEN the controller dispatches a set new password intent.
|
||||||
|
mSetNewPasswordController.dispatchSetNewPasswordIntent();
|
||||||
|
|
||||||
|
// THEN the choose lock activity is launched without fingerprint extras.
|
||||||
|
verify(mUi).launchChooseLock(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void compareFingerprintExtras(Bundle actualBundle) {
|
||||||
|
assertEquals(
|
||||||
|
"Password quality must be something in order to config fingerprint.",
|
||||||
|
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
|
||||||
|
actualBundle.getInt(MINIMUM_QUALITY_KEY));
|
||||||
|
assertTrue(
|
||||||
|
"All disabled preference should be removed.",
|
||||||
|
actualBundle.getBoolean(HIDE_DISABLED_PREFS));
|
||||||
|
assertTrue(
|
||||||
|
"There must be a fingerprint challenge.",
|
||||||
|
actualBundle.getBoolean(EXTRA_KEY_HAS_CHALLENGE));
|
||||||
|
assertEquals(
|
||||||
|
"The fingerprint challenge must come from the FingerprintManager",
|
||||||
|
FINGERPRINT_CHALLENGE,
|
||||||
|
actualBundle.getLong(EXTRA_KEY_CHALLENGE));
|
||||||
|
assertTrue(
|
||||||
|
"The request must be a fingerprint set up request.",
|
||||||
|
actualBundle.getBoolean(EXTRA_KEY_FOR_FINGERPRINT));
|
||||||
|
assertEquals(
|
||||||
|
"User id must be equaled to the input one.",
|
||||||
|
CURRENT_UID,
|
||||||
|
actualBundle.getInt(Intent.EXTRA_USER_ID));
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user