package android.app;
+import android.annotation.UserIdInt;
import android.app.ActivityManager.StackInfo;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
reply.writeNoException();
return true;
}
+ case NOTIFY_LOCKED_PROFILE: {
+ data.enforceInterface(IActivityManager.descriptor);
+ final int userId = data.readInt();
+ notifyLockedProfile(userId);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
reply.recycle();
}
+ public void notifyLockedProfile(@UserIdInt int userId) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(userId);
+ mRemote.transact(NOTIFY_LOCKED_PROFILE, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
package com.android.systemui.keyguard;
+import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
private int mDelayedShowingSequence;
/**
+ * Simiar to {@link #mDelayedProfileShowingSequence}, but it is for profile case.
+ */
+ private int mDelayedProfileShowingSequence;
+
+ /**
* If the user has disabled the keyguard, then requests to exit, this is
* how we'll ultimately let them know whether it was successful. We use this
* var being non-null as an indicator that there is an in progress request.
*/
private boolean mPendingLock;
+ private boolean mLockLater;
+
private boolean mWakeAndUnlocking;
private IKeyguardDrawnCallback mDrawnCallback;
mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
|| !mLockPatternUtils.isSecure(currentUser);
long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
-
+ mLockLater = false;
if (mExitSecureCallback != null) {
if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
try {
} else if ((why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT && timeout > 0)
|| (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
doKeyguardLaterLocked(timeout);
+ mLockLater = true;
} else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
mPendingLock = true;
}
resetStateLocked();
mPendingReset = false;
}
+
if (mPendingLock) {
doKeyguardLocked(null);
mPendingLock = false;
}
+
+ // We do not have timeout and power button instant lock setting for profile lock.
+ // So we use the personal setting if there is any. But if there is no device
+ // we need to make sure we lock it immediately when the screen is off.
+ if (!mLockLater) {
+ doKeyguardForChildProfilesLocked();
+ }
+
}
- doKeyguardForChildProfilesLocked();
KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why);
}
// 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);
+ timeout = Math.max(timeout, 0);
}
return timeout;
}
for (UserInfo info : profiles) {
if (mLockPatternUtils.isSeparateProfileChallengeEnabled(info.id)) {
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.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- userWhen, lockSender);
+ if (userTimeout == 0) {
+ doKeyguardForChildProfilesLocked();
+ } else {
+ long userWhen = SystemClock.elapsedRealtime() + userTimeout;
+ Intent lockIntent = new Intent(DELAYED_LOCK_PROFILE_ACTION);
+ lockIntent.putExtra("seq", mDelayedProfileShowingSequence);
+ lockIntent.putExtra(Intent.EXTRA_USER_ID, info.id);
+ PendingIntent lockSender = PendingIntent.getBroadcast(
+ mContext, 0, lockIntent, PendingIntent.FLAG_CANCEL_CURRENT);
+ mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ userWhen, lockSender);
+ }
}
}
}
mDelayedShowingSequence++;
}
+ private void cancelDoKeyguardForChildProfilesLocked() {
+ mDelayedProfileShowingSequence++;
+ }
+
/**
* Let's us know when the device is waking up.
*/
synchronized (this) {
mDeviceInteractive = true;
cancelDoKeyguardLaterLocked();
+ cancelDoKeyguardForChildProfilesLocked();
if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence);
notifyStartedWakingUp();
}
private void lockProfile(int userId) {
mTrustManager.setDeviceLockedForUser(userId, true);
+ notifyLockedProfile(userId);
}
private boolean shouldWaitForProvisioning() {
}
}
} else if (DELAYED_LOCK_PROFILE_ACTION.equals(intent.getAction())) {
+ final int sequence = intent.getIntExtra("seq", 0);
int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, 0);
if (userId != 0) {
synchronized (KeyguardViewMediator.this) {
- lockProfile(userId);
+ if (mDelayedProfileShowingSequence == sequence) {
+ lockProfile(userId);
+ }
}
}
}
}
}
+ private void notifyLockedProfile(@UserIdInt int userId) {
+ try {
+ ActivityManagerNative.getDefault().notifyLockedProfile(userId);
+ } catch (RemoteException e) {
+ }
+ }
+
/**
* Handle message sent by {@link #showLocked}.
* @see #SHOW
import org.xmlpull.v1.XmlSerializer;
import android.Manifest;
+import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
+ android.Manifest.permission.DEVICE_POWER);
}
- final int user = UserHandle.myUserId();
synchronized(this) {
long ident = Binder.clearCallingIdentity();
try {
- if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
- startHomeActivityLocked(user, "setLockScreenShown");
- }
if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
updateSleepIfNeededLocked();
}
@Override
+ public void notifyLockedProfile(@UserIdInt int userId) {
+ try {
+ if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
+ throw new SecurityException("Only privileged app can call notifyLockedProfile");
+ }
+ } catch (RemoteException ex) {
+ throw new SecurityException("Fail to check is caller a privileged app", ex);
+ }
+
+ synchronized (this) {
+ if (mStackSupervisor.isFocusedUserLockedProfile()) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ final int currentUserId = mUserController.getCurrentUserIdLocked();
+ startHomeActivityLocked(currentUserId, "notifyProfileLocked");
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+ }
+
+ @Override
public void stopAppSwitches() {
if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
!= PackageManager.PERMISSION_GRANTED) {