blob: 57aa8c17d1d1a4fed4963f29e700a8046b630c04 [file] [log] [blame]
/*
* 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.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
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.IBinder;
import android.os.UserManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.Utils;
/**
* 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(Bundle chooseLockFingerprintExtras);
}
/**
* Which user is setting new password.
*/
private final int mTargetUserId;
private final PackageManager mPackageManager;
@Nullable private final IFingerprintManager mFingerprintManager;
private final DevicePolicyManager mDevicePolicyManager;
private final Ui mUi;
public static SetNewPasswordController create(Context context, Ui ui, Intent intent,
IBinder activityToken) {
// Trying to figure out which user is setting new password. If it is
// ACTION_SET_NEW_PARENT_PROFILE_PASSWORD or the calling user is not allowed to set
// separate profile challenge, it is the current user to set new password. Otherwise,
// it is the user who starts this activity setting new password.
int userId = ActivityManager.getCurrentUser();
if (ACTION_SET_NEW_PASSWORD.equals(intent.getAction())) {
final int callingUserId = Utils.getSecureTargetUser(activityToken,
UserManager.get(context), null, intent.getExtras()).getIdentifier();
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
if (lockPatternUtils.isSeparateProfileChallengeAllowed(callingUserId)) {
userId = callingUserId;
}
}
// Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details.
final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context);
final IFingerprintManager fingerprintManagerWrapper =
fingerprintManager == null
? null
: new FingerprintManagerWrapper(fingerprintManager);
return new SetNewPasswordController(userId,
context.getPackageManager(),
fingerprintManagerWrapper,
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE), ui);
}
@VisibleForTesting
SetNewPasswordController(
int targetUserId,
PackageManager packageManager,
IFingerprintManager fingerprintManager,
DevicePolicyManager devicePolicyManager,
Ui ui) {
mTargetUserId = targetUserId;
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() {
final Bundle extras;
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
&& mFingerprintManager != null
&& mFingerprintManager.isHardwareDetected()
&& !mFingerprintManager.hasEnrolledFingerprints(mTargetUserId)
&& !isFingerprintDisabledByAdmin()) {
extras = getFingerprintChooseLockExtras();
} else {
extras = new Bundle();
}
// No matter we show fingerprint options or not, we should tell the next activity which
// user is setting new password.
extras.putInt(Intent.EXTRA_USER_ID, mTargetUserId);
mUi.launchChooseLock(extras);
}
private Bundle getFingerprintChooseLockExtras() {
Bundle chooseLockExtras = new Bundle();
long challenge = mFingerprintManager.preEnroll();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
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);
return chooseLockExtras;
}
private boolean isFingerprintDisabledByAdmin() {
int disabledFeatures =
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mTargetUserId);
return (disabledFeatures & KEYGUARD_DISABLE_FINGERPRINT) != 0;
}
}