OSDN Git Service

Show launcher when profile is locked immediately
authorTony Mak <tonymak@google.com>
Mon, 21 Mar 2016 12:07:16 +0000 (12:07 +0000)
committerTony Mak <tonymak@google.com>
Mon, 21 Mar 2016 13:54:32 +0000 (13:54 +0000)
Previously, we show launcher when keyguard is dismissed.
It introduces these issues:
1. There can be no device lock
2. user could take a quick peek of the work app

Current behavior:
1. We now show launcher once the work profile is locked.
2. Lock profile immediately if there is no device lock
3. Add cancel "lockProfileLater" logic

Bug: 27241680
Bug: 27673460
Change-Id: I765aa22d4c8ae5017c1611f5a340a4b33d463b1e

core/java/android/app/ActivityManagerNative.java
core/java/android/app/IActivityManager.java
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
services/core/java/com/android/server/am/ActivityManagerService.java

index 811a05b..5f317b0 100644 (file)
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.UserIdInt;
 import android.app.ActivityManager.StackInfo;
 import android.app.assist.AssistContent;
 import android.app.assist.AssistStructure;
@@ -2942,6 +2943,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
             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);
@@ -6894,5 +6902,17 @@ class ActivityManagerProxy implements IActivityManager
         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;
 }
index 8e87e26..d0c21f5 100644 (file)
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.UserIdInt;
 import android.app.ActivityManager.RunningServiceInfo;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackInfo;
@@ -628,6 +629,8 @@ public interface IActivityManager extends IInterface {
 
     public void removeStack(int stackId) throws RemoteException;
 
+    public void notifyLockedProfile(@UserIdInt int userId) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -1010,4 +1013,5 @@ public interface IActivityManager extends IInterface {
     int RESIZE_PINNED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 370;
     int IS_VR_PACKAGE_ENABLED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 371;
     int SWAP_DOCKED_AND_FULLSCREEN_STACK = IBinder.FIRST_CALL_TRANSACTION + 372;
+    int NOTIFY_LOCKED_PROFILE = IBinder.FIRST_CALL_TRANSACTION + 373;
 }
index 02b860c..a5dfc4b 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard;
 
+import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
@@ -253,6 +254,11 @@ public class KeyguardViewMediator extends SystemUI {
     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.
@@ -327,6 +333,8 @@ public class KeyguardViewMediator extends SystemUI {
      */
     private boolean mPendingLock;
 
+    private boolean mLockLater;
+
     private boolean mWakeAndUnlocking;
     private IKeyguardDrawnCallback mDrawnCallback;
 
@@ -709,7 +717,7 @@ public class KeyguardViewMediator extends SystemUI {
                     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 {
@@ -726,6 +734,7 @@ public class KeyguardViewMediator extends SystemUI {
             } 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;
             }
@@ -753,12 +762,20 @@ public class KeyguardViewMediator extends SystemUI {
                 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);
     }
 
@@ -791,6 +808,7 @@ public class KeyguardViewMediator extends SystemUI {
             // 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;
     }
@@ -823,13 +841,18 @@ public class KeyguardViewMediator extends SystemUI {
         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);
+                }
             }
         }
     }
@@ -848,6 +871,10 @@ public class KeyguardViewMediator extends SystemUI {
         mDelayedShowingSequence++;
     }
 
+    private void cancelDoKeyguardForChildProfilesLocked() {
+        mDelayedProfileShowingSequence++;
+    }
+
     /**
      * Let's us know when the device is waking up.
      */
@@ -857,6 +884,7 @@ public class KeyguardViewMediator extends SystemUI {
         synchronized (this) {
             mDeviceInteractive = true;
             cancelDoKeyguardLaterLocked();
+            cancelDoKeyguardForChildProfilesLocked();
             if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence);
             notifyStartedWakingUp();
         }
@@ -1179,6 +1207,7 @@ public class KeyguardViewMediator extends SystemUI {
 
     private void lockProfile(int userId) {
         mTrustManager.setDeviceLockedForUser(userId, true);
+        notifyLockedProfile(userId);
     }
 
     private boolean shouldWaitForProvisioning() {
@@ -1300,10 +1329,13 @@ public class KeyguardViewMediator extends SystemUI {
                     }
                 }
             } 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);
+                        }
                     }
                 }
             }
@@ -1505,6 +1537,13 @@ public class KeyguardViewMediator extends SystemUI {
         }
     }
 
+    private void notifyLockedProfile(@UserIdInt int userId) {
+        try {
+            ActivityManagerNative.getDefault().notifyLockedProfile(userId);
+        } catch (RemoteException e) {
+        }
+    }
+
     /**
      * Handle message sent by {@link #showLocked}.
      * @see #SHOW
index 4f0f770..30cc9d0 100644 (file)
@@ -63,6 +63,7 @@ import org.xmlpull.v1.XmlPullParserException;
 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;
@@ -11390,13 +11391,9 @@ public final class ActivityManagerService extends ActivityManagerNative
                     + 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();
@@ -11407,6 +11404,29 @@ public final class ActivityManagerService extends ActivityManagerNative
     }
 
     @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) {