Merge "Create work challenge timeout"
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 2c12317..23e4d97 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -248,8 +248,9 @@
* @hide
*/
public boolean isDeviceLocked(int userId) {
+ ITrustManager trustManager = getTrustManager();
try {
- return mTrustManager.isDeviceLocked(userId);
+ return trustManager.isDeviceLocked(userId);
} catch (RemoteException e) {
return false;
}
@@ -273,13 +274,22 @@
* @hide
*/
public boolean isDeviceSecure(int userId) {
+ ITrustManager trustManager = getTrustManager();
try {
- return mTrustManager.isDeviceSecure(userId);
+ return trustManager.isDeviceSecure(userId);
} catch (RemoteException e) {
return false;
}
}
+ private synchronized ITrustManager getTrustManager() {
+ if (mTrustManager == null) {
+ mTrustManager = ITrustManager.Stub.asInterface(
+ ServiceManager.getService(Context.TRUST_SERVICE));
+ }
+ return mTrustManager;
+ }
+
/**
* @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD}
* and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED}
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 2dea545..a3fe6ab 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -29,6 +29,7 @@
void registerTrustListener(in ITrustListener trustListener);
void unregisterTrustListener(in ITrustListener trustListener);
void reportKeyguardShowingChanged();
+ void setDeviceLockedForUser(int userId, boolean locked);
boolean isDeviceLocked(int userId);
boolean isDeviceSecure(int userId);
}
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index aff69f0..ee591d3 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -51,6 +51,21 @@
}
/**
+ * Changes the lock status for the given user. This is only applicable to Managed Profiles,
+ * other users should be handled by Keyguard.
+ *
+ * @param userId The id for the user to be locked/unlocked.
+ * @param locked The value for that user's locked state.
+ */
+ public void setDeviceLockedForUser(int userId, boolean locked) {
+ try {
+ mService.setDeviceLockedForUser(userId, locked);
+ } catch (RemoteException e) {
+ onError(e);
+ }
+ }
+
+ /**
* Reports that user {@param userId} has tried to unlock the device.
*
* @param successful if true, the unlock attempt was successful.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index eee685f..f7d0b71 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -32,6 +32,7 @@
import android.content.pm.UserInfo;
import android.media.AudioManager;
import android.media.SoundPool;
+import android.os.Binder;
import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.Handler;
@@ -43,6 +44,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.StorageManager;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -135,6 +137,8 @@
private static final String DELAYED_KEYGUARD_ACTION =
"com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
+ private static final String DELAYED_LOCK_PROFILE_ACTION =
+ "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK";
// used for handler messages
private static final int SHOW = 2;
@@ -322,6 +326,8 @@
private boolean mWakeAndUnlocking;
private IKeyguardDrawnCallback mDrawnCallback;
+ private boolean mIsPerUserLock;
+
KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@Override
@@ -565,6 +571,8 @@
mShowKeyguardWakeLock.setReferenceCounted(false);
mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));
+ mContext.registerReceiver(
+ mBroadcastReceiver, new IntentFilter(DELAYED_LOCK_PROFILE_ACTION));
mKeyguardDisplayManager = new KeyguardDisplayManager(mContext);
@@ -637,6 +645,7 @@
doKeyguardLocked(null);
mUpdateMonitor.registerCallback(mUpdateCallback);
}
+ mIsPerUserLock = StorageManager.isFileBasedEncryptionEnabled();
// Most services aren't available until the system reaches the ready state, so we
// send it here when the device first boots.
maybeSendUserPresentBroadcast();
@@ -660,7 +669,7 @@
final boolean lockImmediately =
mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
|| !mLockPatternUtils.isSecure(currentUser);
- long timeout = getLockTimeout();
+ long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
if (mExitSecureCallback != null) {
if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
@@ -710,10 +719,11 @@
mPendingLock = false;
}
}
+ doKeyguardLaterLockedForChildProfiles();
KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why);
}
- private long getLockTimeout() {
+ private long getLockTimeout(int userId) {
// if the screen turned off because of timeout or the user hit the power button
// and we don't need to lock immediately, set an alarm
// to enable it a little bit later (i.e, give the user a chance
@@ -721,10 +731,6 @@
// having to unlock the screen)
final ContentResolver cr = mContext.getContentResolver();
- // From DisplaySettings
- long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
- KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
-
// From SecuritySettings
final long lockAfterTimeout = Settings.Secure.getInt(cr,
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
@@ -732,21 +738,28 @@
// From DevicePolicyAdmin
final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
- .getMaximumTimeToLock(null, KeyguardUpdateMonitor.getCurrentUser());
+ .getMaximumTimeToLock(null, userId);
long timeout;
- if (policyTimeout > 0) {
+
+ UserInfo user = UserManager.get(mContext).getUserInfo(userId);
+ if ((!user.isManagedProfile() && StorageManager.isFileBasedEncryptionEnabled())
+ || policyTimeout <= 0) {
+ timeout = lockAfterTimeout;
+ } else {
+ // From DisplaySettings
+ long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
+ KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
+
// policy in effect. Make sure we don't go beyond policy limit.
displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout);
- } else {
- timeout = lockAfterTimeout;
}
return timeout;
}
private void doKeyguardLaterLocked() {
- long timeout = getLockTimeout();
+ long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
if (timeout == 0) {
doKeyguardLocked(null);
} else {
@@ -764,6 +777,25 @@
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
+ mDelayedShowingSequence);
+ doKeyguardLaterLockedForChildProfiles();
+ }
+
+ private void doKeyguardLaterLockedForChildProfiles() {
+ UserManager um = UserManager.get(mContext);
+ List<UserInfo> profiles = um.getEnabledProfiles(UserHandle.myUserId());
+ if (StorageManager.isFileBasedEncryptionEnabled() && profiles.size() > 1) {
+ for (UserInfo info : profiles) {
+ if (info.id != UserHandle.myUserId() && info.isManagedProfile()) {
+ long userTimeout = getLockTimeout(info.id);
+ long userWhen = SystemClock.elapsedRealtime() + userTimeout;
+ Intent lockIntent = new Intent(DELAYED_LOCK_PROFILE_ACTION);
+ lockIntent.putExtra(Intent.EXTRA_USER_ID, info.id);
+ PendingIntent lockSender = PendingIntent.getBroadcast(
+ mContext, 0, lockIntent, PendingIntent.FLAG_CANCEL_CURRENT);
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, userWhen, lockSender);
+ }
+ }
+ }
}
private void cancelDoKeyguardLaterLocked() {
@@ -1099,6 +1131,10 @@
showLocked(options);
}
+ private void lockProfile(int userId) {
+ mTrustManager.setDeviceLockedForUser(userId, true);
+ }
+
private boolean shouldWaitForProvisioning() {
return !mUpdateMonitor.isDeviceProvisioned() && !isSecure();
}
@@ -1213,8 +1249,13 @@
if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
+ sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence);
synchronized (KeyguardViewMediator.this) {
- if (mDelayedShowingSequence == sequence) {
- doKeyguardLocked(null);
+ doKeyguardLocked(null);
+ }
+ } else if (DELAYED_LOCK_PROFILE_ACTION.equals(intent.getAction())) {
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, 0);
+ if (userId != 0) {
+ synchronized (KeyguardViewMediator.this) {
+ lockProfile(userId);
}
}
}
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index d6c6f13..6e7ace5 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -21,6 +21,8 @@
import android.app.admin.DevicePolicyManager;
import android.app.backup.BackupManager;
import android.app.trust.IStrongAuthTracker;
+import android.app.trust.ITrustManager;
+import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -38,6 +40,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.storage.IMountService;
+import android.os.storage.StorageManager;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -675,6 +678,12 @@
// credential has matched
unlockKeystore(credential, userId);
unlockUser(userId, null);
+ UserInfo info = UserManager.get(mContext).getUserInfo(userId);
+ if (StorageManager.isFileBasedEncryptionEnabled() && info.isManagedProfile()) {
+ TrustManager trustManager =
+ (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+ trustManager.setDeviceLockedForUser(userId, false);
+ }
if (shouldReEnroll) {
credentialUtil.setCredential(credential, credential, userId);
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index e9e02c1..5d60c07 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -67,6 +67,7 @@
import android.app.ResultInfo;
import android.app.StatusBarManager;
import android.app.admin.IDevicePolicyManager;
+import android.app.trust.ITrustManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentSender;
@@ -1669,11 +1670,11 @@
}
UserInfo user = getUserInfo(userId);
- // TODO: Timeout for work challenge
- if (user.isManagedProfile() && StorageManager.isFileBasedEncryptionEnabled()) {
- KeyguardManager km = (KeyguardManager) mService.mContext
- .getSystemService(Context.KEYGUARD_SERVICE);
-
+ KeyguardManager km = (KeyguardManager) mService.mContext
+ .getSystemService(Context.KEYGUARD_SERVICE);
+ if (user.isManagedProfile()
+ && StorageManager.isFileBasedEncryptionEnabled()
+ && km.isDeviceLocked(userId)) {
IIntentSender target = mService.getIntentSenderLocked(
ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent },
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index f9d29ac..f4869fc 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -53,6 +53,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.StorageManager;
import android.provider.Settings;
import android.service.trust.TrustAgentService;
import android.util.ArraySet;
@@ -102,6 +103,7 @@
private static final int MSG_START_USER = 7;
private static final int MSG_CLEANUP_USER = 8;
private static final int MSG_SWITCH_USER = 9;
+ private static final int MSG_SET_DEVICE_LOCKED = 10;
private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
@@ -288,6 +290,19 @@
}
}
+ public void setDeviceLockedForUser(int userId, boolean locked) {
+ if (StorageManager.isFileBasedEncryptionEnabled()) {
+ UserInfo info = mUserManager.getUserInfo(userId);
+ if (info.isManagedProfile()) {
+ synchronized (mDeviceLockedForUser) {
+ mDeviceLockedForUser.put(userId, locked);
+ }
+ } else {
+ Log.wtf(TAG, "Requested to change lock state for non-profile user " + userId);
+ }
+ }
+ }
+
boolean isDeviceLockedInner(int userId) {
synchronized (mDeviceLockedForUser) {
return mDeviceLockedForUser.get(userId, true);
@@ -655,7 +670,9 @@
public boolean isDeviceLocked(int userId) throws RemoteException {
userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
- userId = resolveProfileParent(userId);
+ if (!StorageManager.isFileBasedEncryptionEnabled()) {
+ userId = resolveProfileParent(userId);
+ }
return isDeviceLockedInner(userId);
}
@@ -762,6 +779,12 @@
private String dumpHex(int i) {
return "0x" + Integer.toHexString(i);
}
+
+ @Override
+ public void setDeviceLockedForUser(int userId, boolean value) {
+ mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
+ .sendToTarget();
+ }
};
private int resolveProfileParent(int userId) {
@@ -806,6 +829,9 @@
mCurrentUser = msg.arg1;
refreshDeviceLockedForUser(UserHandle.USER_ALL);
break;
+ case MSG_SET_DEVICE_LOCKED:
+ setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
+ break;
}
}
};