Allow direct-boot aware activity to show before profile is unlocked
Work profile challenge is shown by intercepting normal activity launching and replacing it with the confirm credential activity. For direct boot aware activities, they should be able to be displayed when the work profile is still locked, so add a conditional in the activity intercepting logic to bypass work challenge in this case. Also launching work profile activities from notification is handled specially in order to avoid dismissing the notification if the work challenge is canceled, so add similar logic there to allow direct boot aware activity to go through. Bug: 30296144 Change-Id: Ib6395271cee2d4781009bb08d50351d73824de0c
This commit is contained in:
@@ -3017,6 +3017,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
reply.writeNoException();
|
||||
return true;
|
||||
}
|
||||
case CAN_BYPASS_WORK_CHALLENGE: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
final PendingIntent intent = PendingIntent.CREATOR.createFromParcel(data);
|
||||
final boolean result = canBypassWorkChallenge(intent);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(result ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.onTransact(code, data, reply, flags);
|
||||
@@ -7091,6 +7099,20 @@ class ActivityManagerProxy implements IActivityManager
|
||||
reply.recycle();
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public boolean canBypassWorkChallenge(PendingIntent intent)
|
||||
throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
intent.writeToParcel(data, 0);
|
||||
mRemote.transact(CAN_BYPASS_WORK_CHALLENGE, data, reply, 0);
|
||||
reply.readException();
|
||||
final int result = reply.readInt();
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
private IBinder mRemote;
|
||||
}
|
||||
|
||||
@@ -671,6 +671,18 @@ public interface IActivityManager extends IInterface {
|
||||
*/
|
||||
public void setHasTopUi(boolean hasTopUi) throws RemoteException;
|
||||
|
||||
/**
|
||||
* Returns if the target of the PendingIntent can be fired directly, without triggering
|
||||
* a work profile challenge. This can happen if the PendingIntent is to start direct-boot
|
||||
* aware activities, and the target user is in RUNNING_LOCKED state, i.e. we should allow
|
||||
* direct-boot aware activity to bypass work challenge when the user hasn't unlocked yet.
|
||||
* @param intent the {@link PendingIntent} to be tested.
|
||||
* @return {@code true} if the intent should not trigger a work challenge, {@code false}
|
||||
* otherwise.
|
||||
* @throws RemoteException
|
||||
*/
|
||||
public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException;
|
||||
|
||||
/*
|
||||
* Private non-Binder interfaces
|
||||
*/
|
||||
@@ -1062,4 +1074,5 @@ public interface IActivityManager extends IInterface {
|
||||
int SET_VR_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 377;
|
||||
int SET_RENDER_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 378;
|
||||
int SET_HAS_TOP_UI = IBinder.FIRST_CALL_TRANSACTION + 379;
|
||||
int CAN_BYPASS_WORK_CHALLENGE = IBinder.FIRST_CALL_TRANSACTION + 380;
|
||||
}
|
||||
|
||||
@@ -1944,9 +1944,18 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
.getIdentifier();
|
||||
if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
|
||||
&& mKeyguardManager.isDeviceLocked(userId)) {
|
||||
if (startWorkChallengeIfNecessary(userId,
|
||||
intent.getIntentSender(), notificationKey)) {
|
||||
// Show work challenge, do not run pendingintent and
|
||||
boolean canBypass = false;
|
||||
try {
|
||||
canBypass = ActivityManagerNative.getDefault()
|
||||
.canBypassWorkChallenge(intent);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
// For direct-boot aware activities, they can be shown when
|
||||
// the device is still locked without triggering the work
|
||||
// challenge.
|
||||
if ((!canBypass) && startWorkChallengeIfNecessary(userId,
|
||||
intent.getIntentSender(), notificationKey)) {
|
||||
// Show work challenge, do not run PendingIntent and
|
||||
// remove notification
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22198,4 +22198,22 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
Binder.restoreCallingIdentity(callingId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
|
||||
final int userId = intent.getCreatorUserHandle().getIdentifier();
|
||||
if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
|
||||
return false;
|
||||
}
|
||||
IIntentSender target = intent.getTarget();
|
||||
if (!(target instanceof PendingIntentRecord)) {
|
||||
return false;
|
||||
}
|
||||
final PendingIntentRecord record = (PendingIntentRecord) target;
|
||||
final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
|
||||
record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
|
||||
// For direct boot aware activities, they can be shown without triggering a work challenge
|
||||
// before the profile user is unlocked.
|
||||
return rInfo != null && rInfo.activityInfo != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
|
||||
import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.KeyguardManager;
|
||||
import android.app.admin.DevicePolicyManagerInternal;
|
||||
@@ -210,6 +211,11 @@ class ActivityStartInterceptor {
|
||||
if (!mService.mUserController.shouldConfirmCredentials(userId)) {
|
||||
return null;
|
||||
}
|
||||
// Allow direct boot aware activity to be displayed before the user is unlocked.
|
||||
if (aInfo.directBootAware && mService.mUserController.isUserRunningLocked(userId,
|
||||
ActivityManager.FLAG_AND_LOCKED)) {
|
||||
return null;
|
||||
}
|
||||
final IIntentSender target = mService.getIntentSenderLocked(
|
||||
INTENT_SENDER_ACTIVITY, callingPackage,
|
||||
Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent },
|
||||
|
||||
Reference in New Issue
Block a user