Merge "Added an onDeviceUnlockLockout callback to TrustAgentService."

This commit is contained in:
Zac Iqbal
2017-01-21 01:35:39 +00:00
committed by Android (Google) Code Review
9 changed files with 95 additions and 7 deletions

View File

@@ -38787,6 +38787,7 @@ package android.service.trust {
method public final android.os.IBinder onBind(android.content.Intent);
method public boolean onConfigure(java.util.List<android.os.PersistableBundle>);
method public void onDeviceLocked();
method public void onDeviceUnlockLockout(long);
method public void onDeviceUnlocked();
method public void onTrustTimeout();
method public void onUnlockAttempt(boolean);

View File

@@ -25,6 +25,7 @@ import android.app.trust.ITrustListener;
*/
interface ITrustManager {
void reportUnlockAttempt(boolean successful, int userId);
void reportUnlockLockout(int timeoutMs, int userId);
void reportEnabledTrustAgentsChanged(int userId);
void registerTrustListener(in ITrustListener trustListener);
void unregisterTrustListener(in ITrustListener trustListener);

View File

@@ -80,6 +80,26 @@ public class TrustManager {
}
}
/**
* Reports that user {@param userId} has entered a temporary device lockout.
*
* This generally occurs when the user has unsuccessfully tried to unlock the device too many
* times. The user will then be unable to unlock the device until a set amount of time has
* elapsed.
*
* @param timeout The amount of time that needs to elapse, in milliseconds, until the user may
* attempt to unlock the device again.
*
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
*/
public void reportUnlockLockout(int timeoutMs, int userId) {
try {
mService.reportUnlockLockout(timeoutMs, userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Reports that the list of enabled trust agents changed for user {@param userId}.
*

View File

@@ -24,6 +24,7 @@ import android.service.trust.ITrustAgentServiceCallback;
*/
interface ITrustAgentService {
oneway void onUnlockAttempt(boolean successful);
oneway void onUnlockLockout(int timeoutMs);
oneway void onTrustTimeout();
oneway void onDeviceLocked();
oneway void onDeviceUnlocked();

View File

@@ -123,6 +123,7 @@ public class TrustAgentService extends Service {
private static final int MSG_TRUST_TIMEOUT = 3;
private static final int MSG_DEVICE_LOCKED = 4;
private static final int MSG_DEVICE_UNLOCKED = 5;
private static final int MSG_UNLOCK_LOCKOUT = 6;
/**
* Class containing raw data for a given configuration request.
@@ -151,6 +152,9 @@ public class TrustAgentService extends Service {
case MSG_UNLOCK_ATTEMPT:
onUnlockAttempt(msg.arg1 != 0);
break;
case MSG_UNLOCK_LOCKOUT:
onDeviceUnlockLockout(msg.arg1);
break;
case MSG_CONFIGURE:
ConfigurationData data = (ConfigurationData) msg.obj;
boolean result = onConfigure(data.options);
@@ -226,6 +230,21 @@ public class TrustAgentService extends Service {
public void onDeviceUnlocked() {
}
/**
* Called when the device enters a temporary unlock lockout.
*
* <p>This occurs when the user has consecutively failed to unlock the device too many times,
* and must wait until a timeout has passed to perform another attempt. The user may then only
* use strong authentication mechanisms (PIN, pattern or password) to unlock the device.
* Calls to {@link #grantTrust(CharSequence, long, int)} will be ignored until the user has
* unlocked the device and {@link #onDeviceUnlocked()} is called.
*
* @param timeoutMs The amount of time, in milliseconds, that needs to elapse before the user
* can attempt to unlock the device again.
*/
public void onDeviceUnlockLockout(long timeoutMs) {
}
private void onError(String msg) {
Slog.v(TAG, "Remote exception while " + msg);
}
@@ -366,6 +385,11 @@ public class TrustAgentService extends Service {
mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0).sendToTarget();
}
@Override
public void onUnlockLockout(int timeoutMs) {
mHandler.obtainMessage(MSG_UNLOCK_LOCKOUT, timeoutMs, 0).sendToTarget();
}
@Override /* Binder API */
public void onTrustTimeout() {
mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);

View File

@@ -298,6 +298,10 @@ public class LockPatternUtils {
getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
}
public void reportPasswordLockout(int timeoutMs, int userId) {
getTrustManager().reportUnlockLockout(timeoutMs, userId);
}
public int getCurrentFailedPasswordAttempts(int userId) {
return getDevicePolicyManager().getCurrentFailedPasswordAttempts(userId);
}

View File

@@ -290,6 +290,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
monitor.reportFailedStrongAuthUnlockAttempt(userId);
mLockPatternUtils.reportFailedPasswordAttempt(userId);
if (timeoutMs > 0) {
mLockPatternUtils.reportPasswordLockout(timeoutMs, userId);
showTimeoutDialog(userId, timeoutMs);
}
}

View File

@@ -320,6 +320,19 @@ public class TrustAgentWrapper {
}
}
/**
* @see android.service.trust.TrustAgentService#onUnlockLockout(int)
*/
public void onUnlockLockout(int timeoutMs) {
try {
if (mTrustAgentService != null) {
mTrustAgentService.onUnlockLockout(timeoutMs);
}
} catch (RemoteException e) {
onError(e);
}
}
/**
* @see android.service.trust.TrustAgentService#onDeviceLocked()
*/

View File

@@ -105,6 +105,7 @@ public class TrustManagerService extends SystemService {
private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 10;
private static final int MSG_UNLOCK_USER = 11;
private static final int MSG_STOP_USER = 12;
private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
@@ -335,13 +336,16 @@ public class TrustManagerService extends SystemService {
if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) {
int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id);
if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|| !directUnlock) {
if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
+ ": prevented by StrongAuthTracker = 0x"
+ Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
userInfo.id)));
continue;
if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) {
if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|| !directUnlock) {
if (DEBUG)
Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
+ ": prevented by StrongAuthTracker = 0x"
+ Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
userInfo.id)));
continue;
}
}
}
@@ -650,6 +654,15 @@ public class TrustManagerService extends SystemService {
}
}
private void dispatchUnlockLockout(int timeoutMs, int userId) {
for (int i = 0; i < mActiveAgents.size(); i++) {
AgentInfo info = mActiveAgents.valueAt(i);
if (info.userId == userId) {
info.agent.onUnlockLockout(timeoutMs);
}
}
}
// Listeners
private void addListener(ITrustListener listener) {
@@ -744,6 +757,13 @@ public class TrustManagerService extends SystemService {
.sendToTarget();
}
@Override
public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
enforceReportPermission();
mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
.sendToTarget();
}
@Override
public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
enforceReportPermission();
@@ -975,6 +995,9 @@ public class TrustManagerService extends SystemService {
case MSG_DISPATCH_UNLOCK_ATTEMPT:
dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
break;
case MSG_DISPATCH_UNLOCK_LOCKOUT:
dispatchUnlockLockout(msg.arg1, msg.arg2);
break;
case MSG_ENABLED_AGENTS_CHANGED:
refreshAgentList(UserHandle.USER_ALL);
// This is also called when the security mode of a user changes.