Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c6e8ced authored by Tony Mak's avatar Tony Mak
Browse files

Show launcher when profile is locked immediately

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
parent eedcdb04
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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;
}
+4 −0
Original line number Diff line number Diff line
@@ -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;
}
+49 −10
Original line number Diff line number Diff line
@@ -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;
@@ -252,6 +253,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
@@ -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();
            }

        }
        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,8 +841,12 @@ public class KeyguardViewMediator extends SystemUI {
        for (UserInfo info : profiles) {
            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(info.id)) {
                long userTimeout = getLockTimeout(info.id);
                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);
@@ -833,6 +855,7 @@ public class KeyguardViewMediator extends SystemUI {
                }
            }
        }
    }

    private void doKeyguardForChildProfilesLocked() {
        UserManager um = UserManager.get(mContext);
@@ -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,14 +1329,17 @@ 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) {
                        if (mDelayedProfileShowingSequence == sequence) {
                            lockProfile(userId);
                        }
                    }
                }
            }
        }
    };

    public void keyguardDone(boolean authenticated) {
@@ -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
+24 −4
Original line number Diff line number Diff line
@@ -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();
@@ -11406,6 +11403,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)