diff options
4 files changed, 26 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 55cca950a213..0b27a8ad77dc 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -379,6 +379,10 @@ public final class PendingIntentRecord extends IIntentSender.Stub { if (userId == UserHandle.USER_CURRENT) { userId = controller.mUserController.getCurrentOrTargetUserId(); } + // temporarily allow receivers and services to open activities from background if the + // PendingIntent.send() caller was foreground at the time of sendInner() call + final boolean allowTrampoline = uid != callingUid + && controller.mAtmInternal.isUidForeground(callingUid); switch (key.type) { case ActivityManager.INTENT_SENDER_ACTIVITY: @@ -419,7 +423,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { uid, finalIntent, resolvedType, finishedReceiver, code, null, null, requiredPermission, options, (finishedReceiver != null), false, userId, - mAllowBgActivityStartsForBroadcastSender.contains(whitelistToken)); + mAllowBgActivityStartsForBroadcastSender.contains(whitelistToken) + || allowTrampoline); if (sent == ActivityManager.BROADCAST_SUCCESS) { sendFinish = false; } @@ -433,7 +438,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType, key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE, key.packageName, userId, - mAllowBgActivityStartsForServiceSender.contains(whitelistToken)); + mAllowBgActivityStartsForServiceSender.contains(whitelistToken) + || allowTrampoline); } catch (RuntimeException e) { Slog.w(TAG, "Unable to send startService intent", e); } catch (TransactionTooLargeException e) { diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 865ffbd56bee..0652182dca95 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -924,14 +924,15 @@ class ActivityStarter { return false; } // don't abort if the callingUid is in the foreground or is a persistent system process - final boolean isCallingUidForeground = isUidForeground(callingUid); + final boolean isCallingUidForeground = mService.isUidForeground(callingUid); final boolean isCallingUidPersistentSystemProcess = isUidPersistentSystemProcess( callingUid); if (isCallingUidForeground || isCallingUidPersistentSystemProcess) { return false; } // take realCallingUid into consideration - final boolean isRealCallingUidForeground = isUidForeground(realCallingUid); + final boolean isRealCallingUidForeground = mService.isUidForeground( + realCallingUid); final boolean isRealCallingUidPersistentSystemProcess = isUidPersistentSystemProcess( realCallingUid); if (realCallingUid != callingUid) { @@ -976,12 +977,6 @@ class ActivityStarter { return true; } - /** Returns true if uid has a visible window or its process is in a top state. */ - private boolean isUidForeground(int uid) { - return (mService.getUidStateLocked(uid) == ActivityManager.PROCESS_STATE_TOP) - || mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid); - } - /** Returns true if uid is in a persistent state. */ private boolean isUidPersistentSystemProcess(int uid) { return (mService.getUidStateLocked(uid) <= ActivityManager.PROCESS_STATE_PERSISTENT_UI); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index 67b00b2cfbf1..1a5e6a14e733 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -489,4 +489,7 @@ public abstract class ActivityTaskManagerInternal { */ public abstract ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution); + + /** Returns true if uid has a visible window or its process is in a top state. */ + public abstract boolean isUidForeground(int uid); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index ea6f4cc4ddbc..e5a66cb4238f 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -5632,6 +5632,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT); } + boolean isUidForeground(int uid) { + return (getUidStateLocked(uid) == ActivityManager.PROCESS_STATE_TOP) + || mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid); + } + /** * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on * the whitelist @@ -7041,5 +7046,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return ActivityTaskManagerService.this.getTaskSnapshot(taskId, reducedResolution); } } + + @Override + public boolean isUidForeground(int uid) { + synchronized (mGlobalLock) { + return ActivityTaskManagerService.this.isUidForeground(uid); + } + } } } |