Merge "Fingerprint Strong auth timeout" into nyc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
69659cb96d
@@ -416,6 +416,14 @@ public class DevicePolicyManager {
|
|||||||
*/
|
*/
|
||||||
public static final int NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED = 3;
|
public static final int NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default and maximum timeout in milliseconds after which unlocking with weak auth times out,
|
||||||
|
* i.e. the user has to use a strong authentication method like password, PIN or pattern.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final long DEFAULT_STRONG_AUTH_TIMEOUT_MS = 72 * 60 * 60 * 1000; // 72h
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
|
* A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
|
||||||
* allows a mobile device management application or NFC programmer application which starts
|
* allows a mobile device management application or NFC programmer application which starts
|
||||||
@@ -2335,6 +2343,78 @@ public class DevicePolicyManager {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by a device/profile owner to set the timeout after which unlocking with secondary, non
|
||||||
|
* strong auth (e.g. fingerprint, trust agents) times out, i.e. the user has to use a strong
|
||||||
|
* authentication method like password, pin or pattern.
|
||||||
|
*
|
||||||
|
* <p>This timeout is used internally to reset the timer to require strong auth again after
|
||||||
|
* specified timeout each time it has been successfully used.
|
||||||
|
*
|
||||||
|
* <p>Fingerprint can also be disabled altogether using {@link #KEYGUARD_DISABLE_FINGERPRINT}.
|
||||||
|
*
|
||||||
|
* <p>Trust agents can also be disabled altogether using {@link #KEYGUARD_DISABLE_TRUST_AGENTS}.
|
||||||
|
*
|
||||||
|
* <p>The calling device admin must be a device or profile owner. If it is not,
|
||||||
|
* a {@link SecurityException} will be thrown.
|
||||||
|
*
|
||||||
|
* <p>This method can be called on the {@link DevicePolicyManager} instance returned by
|
||||||
|
* {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
|
||||||
|
* profile.
|
||||||
|
*
|
||||||
|
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
|
||||||
|
* @param timeoutMs The new timeout, after which the user will have to unlock with strong
|
||||||
|
* authentication method. If the timeout is lower than 1 hour (minimum) or higher than
|
||||||
|
* 72 hours (default and maximum) an {@link IllegalArgumentException} is thrown.
|
||||||
|
*
|
||||||
|
* @throws SecurityException if {@code admin} is not a device or profile owner.
|
||||||
|
* @throws IllegalArgumentException if the timeout is lower than 1 hour (minimum) or higher than
|
||||||
|
* 72 hours (default and maximum)
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void setRequiredStrongAuthTimeout(@NonNull ComponentName admin,
|
||||||
|
long timeoutMs) {
|
||||||
|
if (mService != null) {
|
||||||
|
try {
|
||||||
|
mService.setRequiredStrongAuthTimeout(admin, timeoutMs, mParentInstance);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine for how long the user will be able to use secondary, non strong auth for
|
||||||
|
* authentication, since last strong method authentication (password, pin or pattern) was used.
|
||||||
|
* After the returned timeout the user is required to use strong authentication method.
|
||||||
|
*
|
||||||
|
* <p>This method can be called on the {@link DevicePolicyManager} instance
|
||||||
|
* returned by {@link #getParentProfileInstance(ComponentName)} in order to retrieve
|
||||||
|
* restrictions on the parent profile.
|
||||||
|
*
|
||||||
|
* @param admin The name of the admin component to check, or {@code null} to aggregate
|
||||||
|
* accross all participating admins.
|
||||||
|
* @return The timeout or default timeout if not configured
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public long getRequiredStrongAuthTimeout(@Nullable ComponentName admin) {
|
||||||
|
return getRequiredStrongAuthTimeout(admin, myUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @hide per-user version */
|
||||||
|
public long getRequiredStrongAuthTimeout(@Nullable ComponentName admin, @UserIdInt int userId) {
|
||||||
|
if (mService != null) {
|
||||||
|
try {
|
||||||
|
return mService.getRequiredStrongAuthTimeout(admin, userId, mParentInstance);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DEFAULT_STRONG_AUTH_TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the device lock immediately, as if the lock screen timeout has expired at the point of
|
* Make the device lock immediately, as if the lock screen timeout has expired at the point of
|
||||||
* this call.
|
* this call.
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ interface IDevicePolicyManager {
|
|||||||
long getMaximumTimeToLock(in ComponentName who, int userHandle, boolean parent);
|
long getMaximumTimeToLock(in ComponentName who, int userHandle, boolean parent);
|
||||||
long getMaximumTimeToLockForUserAndProfiles(int userHandle);
|
long getMaximumTimeToLockForUserAndProfiles(int userHandle);
|
||||||
|
|
||||||
|
void setRequiredStrongAuthTimeout(in ComponentName who, long timeMs, boolean parent);
|
||||||
|
long getRequiredStrongAuthTimeout(in ComponentName who, int userId, boolean parent);
|
||||||
|
|
||||||
void lockNow(boolean parent);
|
void lockNow(boolean parent);
|
||||||
|
|
||||||
void wipeData(int flags);
|
void wipeData(int flags);
|
||||||
|
|||||||
@@ -111,12 +111,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
|
|
||||||
private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
|
private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
|
||||||
|
|
||||||
/**
|
|
||||||
* Milliseconds after unlocking with fingerprint times out, i.e. the user has to use a
|
|
||||||
* strong auth method like password, PIN or pattern.
|
|
||||||
*/
|
|
||||||
private static final long FINGERPRINT_UNLOCK_TIMEOUT_MS = 72 * 60 * 60 * 1000;
|
|
||||||
|
|
||||||
// Callback messages
|
// Callback messages
|
||||||
private static final int MSG_TIME_UPDATE = 301;
|
private static final int MSG_TIME_UPDATE = 301;
|
||||||
private static final int MSG_BATTERY_UPDATE = 302;
|
private static final int MSG_BATTERY_UPDATE = 302;
|
||||||
@@ -608,7 +602,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleStrongAuthTimeout() {
|
private void scheduleStrongAuthTimeout() {
|
||||||
long when = SystemClock.elapsedRealtime() + FINGERPRINT_UNLOCK_TIMEOUT_MS;
|
final DevicePolicyManager dpm =
|
||||||
|
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
|
long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null,
|
||||||
|
sCurrentUser);
|
||||||
Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
|
Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
|
||||||
intent.putExtra(USER_ID, sCurrentUser);
|
intent.putExtra(USER_ID, sCurrentUser);
|
||||||
PendingIntent sender = PendingIntent.getBroadcast(mContext,
|
PendingIntent sender = PendingIntent.getBroadcast(mContext,
|
||||||
|
|||||||
@@ -309,6 +309,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
|
|
||||||
private static final int DEVICE_ADMIN_DEACTIVATE_TIMEOUT = 10000;
|
private static final int DEVICE_ADMIN_DEACTIVATE_TIMEOUT = 10000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum timeout in milliseconds after which unlocking with weak auth times out,
|
||||||
|
* i.e. the user has to use a strong authentication method like password, PIN or pattern.
|
||||||
|
*/
|
||||||
|
private static final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = 1 * 60 * 60 * 1000; // 1h
|
||||||
|
|
||||||
final Context mContext;
|
final Context mContext;
|
||||||
final Injector mInjector;
|
final Injector mInjector;
|
||||||
final IPackageManager mIPackageManager;
|
final IPackageManager mIPackageManager;
|
||||||
@@ -550,6 +556,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
private static final String TAG_PERMITTED_IMES = "permitted-imes";
|
private static final String TAG_PERMITTED_IMES = "permitted-imes";
|
||||||
private static final String TAG_MAX_FAILED_PASSWORD_WIPE = "max-failed-password-wipe";
|
private static final String TAG_MAX_FAILED_PASSWORD_WIPE = "max-failed-password-wipe";
|
||||||
private static final String TAG_MAX_TIME_TO_UNLOCK = "max-time-to-unlock";
|
private static final String TAG_MAX_TIME_TO_UNLOCK = "max-time-to-unlock";
|
||||||
|
private static final String TAG_STRONG_AUTH_UNLOCK_TIMEOUT = "strong-auth-unlock-timeout";
|
||||||
private static final String TAG_MIN_PASSWORD_NONLETTER = "min-password-nonletter";
|
private static final String TAG_MIN_PASSWORD_NONLETTER = "min-password-nonletter";
|
||||||
private static final String TAG_MIN_PASSWORD_SYMBOLS = "min-password-symbols";
|
private static final String TAG_MIN_PASSWORD_SYMBOLS = "min-password-symbols";
|
||||||
private static final String TAG_MIN_PASSWORD_NUMERIC = "min-password-numeric";
|
private static final String TAG_MIN_PASSWORD_NUMERIC = "min-password-numeric";
|
||||||
@@ -604,6 +611,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
|
static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
|
||||||
long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
|
long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
|
||||||
|
|
||||||
|
long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
|
||||||
|
|
||||||
static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0;
|
static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0;
|
||||||
int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE;
|
int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE;
|
||||||
|
|
||||||
@@ -753,6 +762,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
out.attribute(null, ATTR_VALUE, Long.toString(maximumTimeToUnlock));
|
out.attribute(null, ATTR_VALUE, Long.toString(maximumTimeToUnlock));
|
||||||
out.endTag(null, TAG_MAX_TIME_TO_UNLOCK);
|
out.endTag(null, TAG_MAX_TIME_TO_UNLOCK);
|
||||||
}
|
}
|
||||||
|
if (strongAuthUnlockTimeout != DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) {
|
||||||
|
out.startTag(null, TAG_STRONG_AUTH_UNLOCK_TIMEOUT);
|
||||||
|
out.attribute(null, ATTR_VALUE, Long.toString(strongAuthUnlockTimeout));
|
||||||
|
out.endTag(null, TAG_STRONG_AUTH_UNLOCK_TIMEOUT);
|
||||||
|
}
|
||||||
if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
|
if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
|
||||||
out.startTag(null, TAG_MAX_FAILED_PASSWORD_WIPE);
|
out.startTag(null, TAG_MAX_FAILED_PASSWORD_WIPE);
|
||||||
out.attribute(null, ATTR_VALUE, Integer.toString(maximumFailedPasswordsForWipe));
|
out.attribute(null, ATTR_VALUE, Integer.toString(maximumFailedPasswordsForWipe));
|
||||||
@@ -967,6 +981,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
} else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
|
} else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
|
||||||
maximumTimeToUnlock = Long.parseLong(
|
maximumTimeToUnlock = Long.parseLong(
|
||||||
parser.getAttributeValue(null, ATTR_VALUE));
|
parser.getAttributeValue(null, ATTR_VALUE));
|
||||||
|
} else if (TAG_STRONG_AUTH_UNLOCK_TIMEOUT.equals(tag)) {
|
||||||
|
strongAuthUnlockTimeout = Long.parseLong(
|
||||||
|
parser.getAttributeValue(null, ATTR_VALUE));
|
||||||
} else if (TAG_MAX_FAILED_PASSWORD_WIPE.equals(tag)) {
|
} else if (TAG_MAX_FAILED_PASSWORD_WIPE.equals(tag)) {
|
||||||
maximumFailedPasswordsForWipe = Integer.parseInt(
|
maximumFailedPasswordsForWipe = Integer.parseInt(
|
||||||
parser.getAttributeValue(null, ATTR_VALUE));
|
parser.getAttributeValue(null, ATTR_VALUE));
|
||||||
@@ -1218,6 +1235,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
pw.println(minimumPasswordNonLetter);
|
pw.println(minimumPasswordNonLetter);
|
||||||
pw.print(prefix); pw.print("maximumTimeToUnlock=");
|
pw.print(prefix); pw.print("maximumTimeToUnlock=");
|
||||||
pw.println(maximumTimeToUnlock);
|
pw.println(maximumTimeToUnlock);
|
||||||
|
pw.print(prefix); pw.print("strongAuthUnlockTimeout=");
|
||||||
|
pw.println(strongAuthUnlockTimeout);
|
||||||
pw.print(prefix); pw.print("maximumFailedPasswordsForWipe=");
|
pw.print(prefix); pw.print("maximumFailedPasswordsForWipe=");
|
||||||
pw.println(maximumFailedPasswordsForWipe);
|
pw.println(maximumFailedPasswordsForWipe);
|
||||||
pw.print(prefix); pw.print("specifiesGlobalProxy=");
|
pw.print(prefix); pw.print("specifiesGlobalProxy=");
|
||||||
@@ -4222,6 +4241,60 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRequiredStrongAuthTimeout(ComponentName who, long timeoutMs,
|
||||||
|
boolean parent) {
|
||||||
|
if (!mHasFeature) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||||
|
Preconditions.checkArgument(timeoutMs >= MINIMUM_STRONG_AUTH_TIMEOUT_MS,
|
||||||
|
"Timeout must not be lower than the minimum strong auth timeout.");
|
||||||
|
Preconditions.checkArgument(timeoutMs <= DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS,
|
||||||
|
"Timeout must not be higher than the default strong auth timeout.");
|
||||||
|
|
||||||
|
final int userHandle = mInjector.userHandleGetCallingUserId();
|
||||||
|
synchronized (this) {
|
||||||
|
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||||
|
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
|
||||||
|
if (ap.strongAuthUnlockTimeout != timeoutMs) {
|
||||||
|
ap.strongAuthUnlockTimeout = timeoutMs;
|
||||||
|
saveSettingsLocked(userHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a single admin's strong auth unlock timeout or minimum value (strictest) of all
|
||||||
|
* admins if who is null.
|
||||||
|
* Returns default timeout if not configured.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getRequiredStrongAuthTimeout(ComponentName who, int userId, boolean parent) {
|
||||||
|
if (!mHasFeature) {
|
||||||
|
return DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
enforceFullCrossUsersPermission(userId);
|
||||||
|
synchronized (this) {
|
||||||
|
if (who != null) {
|
||||||
|
ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId, parent);
|
||||||
|
return admin != null ? Math.max(admin.strongAuthUnlockTimeout,
|
||||||
|
MINIMUM_STRONG_AUTH_TIMEOUT_MS)
|
||||||
|
: DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the strictest policy across all participating admins.
|
||||||
|
List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userId, parent);
|
||||||
|
|
||||||
|
long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
|
||||||
|
for (int i = 0; i < admins.size(); i++) {
|
||||||
|
strongAuthUnlockTimeout = Math.min(admins.get(i).strongAuthUnlockTimeout,
|
||||||
|
strongAuthUnlockTimeout);
|
||||||
|
}
|
||||||
|
return Math.max(strongAuthUnlockTimeout, MINIMUM_STRONG_AUTH_TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lockNow(boolean parent) {
|
public void lockNow(boolean parent) {
|
||||||
if (!mHasFeature) {
|
if (!mHasFeature) {
|
||||||
|
|||||||
Reference in New Issue
Block a user