Skip to content

Commit

Permalink
DO NOT MERGE Provide fingerprint options for SET_NEW_PASSWORD intent
Browse files Browse the repository at this point in the history
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
  • Loading branch information
stevenckngaa committed Sep 28, 2016
1 parent d76a3ed commit da738b2
Show file tree
Hide file tree
Showing 10 changed files with 440 additions and 13 deletions.
5 changes: 5 additions & 0 deletions AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,11 @@

<activity android:name="ChooseLockGeneric"
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" >
<intent-filter android:priority="1">
<action android:name="android.app.action.SET_NEW_PASSWORD" />
Expand Down
3 changes: 2 additions & 1 deletion res/layout/choose_lock_generic_fingerprint_header.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
-->

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fingerprint_header_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="56dp"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:text="@string/lock_settings_picker_fingerprint_message"
android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
style="@style/FingerprintHeaderStyle" />
6 changes: 6 additions & 0 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,12 @@
<!-- 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>

<!-- 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] -->
<string name="unlock_set_unlock_disabled_summary">Disabled by administrator, encryption policy, or credential storage</string>

Expand Down
6 changes: 6 additions & 0 deletions res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -435,4 +435,10 @@
<item name="android:paddingEnd">56dp</item>
</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>
5 changes: 5 additions & 0 deletions res/xml/security_settings_picker.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@
android:key="unlock_set_managed"
android:persistent="false"/>

<com.android.settingslib.RestrictedPreference
android:key="unlock_skip_fingerprint"
android:title="@string/fingerprint_unlock_skip_fingerprint"
android:persistent="false"/>

</PreferenceScreen>
74 changes: 63 additions & 11 deletions src/com/android/settings/ChooseLockGeneric.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

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.app.Activity;
import android.app.AlertDialog;
Expand All @@ -42,16 +47,17 @@
import android.util.EventLog;
import android.util.Log;
import android.view.accessibility.AccessibilityManager;
import android.widget.TextView;

import com.android.internal.logging.MetricsProto.MetricsEvent;
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.RestrictedPreference;

import java.util.List;

import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

public class ChooseLockGeneric extends SettingsActivity {
public static final String CONFIRM_CREDENTIALS = "confirm_credentials";

Expand All @@ -61,8 +67,8 @@ public Intent getIntent() {
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());

String action = modIntent.getAction();
if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD.equals(action)
|| DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
if (ACTION_SET_NEW_PASSWORD.equals(action)
|| ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
modIntent.putExtra(EXTRA_HIDE_DRAWER, true);
}
return modIntent;
Expand Down Expand Up @@ -90,6 +96,7 @@ public static class ChooseLockGenericFragment extends SettingsPreferenceFragment
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_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 WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
Expand All @@ -101,6 +108,8 @@ public static class ChooseLockGenericFragment extends SettingsPreferenceFragment
private static final int CONFIRM_EXISTING_REQUEST = 100;
private static final int ENABLE_ENCRYPTION_REQUEST = 101;
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 DevicePolicyManager mDPM;
Expand All @@ -119,6 +128,7 @@ public static class ChooseLockGenericFragment extends SettingsPreferenceFragment
private int mUserId;
private boolean mHideDrawer = false;
private ManagedLockPasswordProvider mManagedPasswordProvider;
private boolean mIsSetNewPassword = false;

protected boolean mForFingerprint = false;

Expand All @@ -131,12 +141,15 @@ protected int getMetricsCategory() {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

String chooseLockAction = getActivity().getIntent().getAction();
mFingerprintManager =
(FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mKeyStore = KeyStore.getInstance();
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.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
final boolean confirmCredentials = getActivity().getIntent()
Expand All @@ -154,6 +167,16 @@ public void onCreate(Bundle savedInstanceState) {
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean(
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) {
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
Expand All @@ -168,9 +191,8 @@ public void onCreate(Bundle savedInstanceState) {
UserManager.get(getActivity()),
null,
getActivity().getIntent().getExtras()).getIdentifier();
if (DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(
getActivity().getIntent().getAction()) ||
!mLockPatternUtils.isSeparateProfileChallengeAllowed(targetUser)) {
if (ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction)
|| !mLockPatternUtils.isSeparateProfileChallengeAllowed(targetUser)) {
// Always use parent if explicitely requested or if profile challenge is not
// supported
Bundle arguments = getArguments();
Expand All @@ -180,8 +202,7 @@ public void onCreate(Bundle savedInstanceState) {
mUserId = targetUser;
}

if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD
.equals(getActivity().getIntent().getAction())
if (ACTION_SET_NEW_PASSWORD.equals(chooseLockAction)
&& Utils.isManagedProfile(UserManager.get(getActivity()), mUserId)
&& mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
getActivity().setTitle(R.string.lock_settings_picker_title_profile);
Expand Down Expand Up @@ -216,6 +237,10 @@ public void onCreate(Bundle savedInstanceState) {
protected void addHeaderView() {
if (mForFingerprint) {
setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
if (mIsSetNewPassword) {
((TextView) getHeaderView().findViewById(R.id.fingerprint_header_description))
.setText(R.string.fingerprint_unlock_title);
}
}
}

Expand All @@ -228,6 +253,12 @@ public boolean onPreferenceTreeClick(Preference preference) {
// unlock method to an insecure one
showFactoryResetProtectionWarningDialog(key);
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 {
return setUnlockMethod(key);
}
Expand Down Expand Up @@ -302,6 +333,20 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
getActivity().setResult(resultCode, data);
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 {
getActivity().setResult(Activity.RESULT_CANCELED);
finish();
Expand Down Expand Up @@ -375,6 +420,10 @@ private void updatePreferenceText() {
} else {
removePreference(KEY_UNLOCK_SET_MANAGED);
}

if (!(mForFingerprint && mIsSetNewPassword)) {
removePreference(KEY_SKIP_FINGERPRINT);
}
}

private void updateCurrentPreference() {
Expand Down Expand Up @@ -607,16 +656,19 @@ void updateUnlockMethodAndFinish(int quality, boolean disabled) {
quality = upgradeQuality(quality);
Intent intent = getIntentForUnlockMethod(quality, disabled);
if (intent != null) {
startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
startActivityForResult(intent,
mIsSetNewPassword && mHasChallenge
? CHOOSE_LOCK_BEFORE_FINGERPRINT_REQUEST
: CHOOSE_LOCK_REQUEST);
return;
}

if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
mLockPatternUtils.setSeparateProfileChallengeEnabled(mUserId, true, mUserPassword);
mChooseLockSettingsHelper.utils().clearLock(mUserId);
mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId);
removeAllFingerprintForUserAndFinish(mUserId);
getActivity().setResult(Activity.RESULT_OK);
removeAllFingerprintForUserAndFinish(mUserId);
} else {
removeAllFingerprintForUserAndFinish(mUserId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
*/
public abstract class FingerprintEnrollBase extends InstrumentedActivity
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_TIMEOUT = FingerprintSettings.RESULT_TIMEOUT;

Expand Down
55 changes: 55 additions & 0 deletions src/com/android/settings/password/SetNewPasswordActivity.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
Loading

0 comments on commit da738b2

Please sign in to comment.