summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt1
-rw-r--r--core/java/android/app/trust/ITrustManager.aidl1
-rw-r--r--core/java/android/app/trust/TrustManager.java20
-rw-r--r--core/java/android/service/trust/ITrustAgentService.aidl1
-rw-r--r--core/java/android/service/trust/TrustAgentService.java24
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java4
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java1
-rw-r--r--services/core/java/com/android/server/trust/TrustAgentWrapper.java13
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java37
9 files changed, 95 insertions, 7 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index c39c70a46bfd..ed0f26e93615 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -38772,6 +38772,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);
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index d3d02e59c228..a10de45d115b 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -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);
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 0f5cb6f4b8e1..a64a023fec6b 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -81,6 +81,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}.
*
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
diff --git a/core/java/android/service/trust/ITrustAgentService.aidl b/core/java/android/service/trust/ITrustAgentService.aidl
index f07d0d032ed1..22b4d09e5f70 100644
--- a/core/java/android/service/trust/ITrustAgentService.aidl
+++ b/core/java/android/service/trust/ITrustAgentService.aidl
@@ -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();
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 9d7ffad5052e..0d5177d23413 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -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);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index a43f3a72782c..a29882b497b4 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -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);
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 91c943de756c..8cdb906a0e56 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -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);
}
}
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index e7c5384b9932..6c1648cb0d16 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -321,6 +321,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()
*/
public void onDeviceLocked() {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index c69b87c53763..71b725e10769 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -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) {
@@ -745,6 +758,13 @@ public class TrustManagerService extends SystemService {
}
@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();
// coalesce refresh messages.
@@ -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.