summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michal Karpinski <mkarpinski@google.com> 2019-01-12 14:20:38 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-01-12 14:20:38 +0000
commitceeadaed26425b59d509eb2c9e152cb422c68a65 (patch)
treee7a5ed01f010553a8631a035e9b9ae73e564a32e
parent6c6528f648405cb89112e2f90d5d71359136c1a7 (diff)
parentc8aa91bd0a0af06146f1ba60aa049c77316fff59 (diff)
Merge "Temporarily whitelist processes to open activities from background when service-based PendingIntent was whitelisted"
-rw-r--r--core/java/android/app/ActivityManagerInternal.java4
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java32
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java7
-rw-r--r--services/core/java/com/android/server/am/PendingIntentRecord.java8
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java2
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java4
6 files changed, 50 insertions, 7 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 9d44e58112c5..c90e40411240 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -258,8 +258,8 @@ public abstract class ActivityManagerInternal {
Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized,
boolean sticky, int userId, boolean allowBackgroundActivityStarts);
public abstract ComponentName startServiceInPackage(int uid, Intent service,
- String resolvedType, boolean fgRequired, String callingPackage, int userId)
- throws TransactionTooLargeException;
+ String resolvedType, boolean fgRequired, String callingPackage, int userId,
+ boolean allowBackgroundActivityStarts) throws TransactionTooLargeException;
public abstract void disconnectActivityFromServices(Object connectionHolder);
public abstract void cleanUpServices(int userId, ComponentName component, Intent baseIntent);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8ca4193a064f..bab9a6535376 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -130,6 +130,9 @@ public final class ActiveServices {
// calling startForeground() before we ANR + stop it.
static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000;
+ // For how long after a whitelisted service's start its process can start a background activity
+ private static final int SERVICE_BG_ACTIVITY_START_TIMEOUT_MS = 10*1000;
+
final ActivityManagerService mAm;
// Maximum number of services that we allow to start in the background
@@ -398,6 +401,14 @@ public final class ActiveServices {
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
+ return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
+ callingPackage, userId, false);
+ }
+
+ ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
+ int callingPid, int callingUid, boolean fgRequired, String callingPackage,
+ final int userId, boolean allowBackgroundActivityStarts)
+ throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
@@ -622,10 +633,28 @@ public final class ActiveServices {
}
}
+ if (allowBackgroundActivityStarts) {
+ ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
+ if (proc != null) {
+ proc.addAllowBackgroundActivityStartsToken(r);
+ // schedule removal of the whitelisting token after the timeout
+ removeAllowBackgroundActivityStartsServiceToken(proc, r,
+ SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
+ }
+ }
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
+ private void removeAllowBackgroundActivityStartsServiceToken(ProcessRecord proc,
+ ServiceRecord r, int delayMillis) {
+ mAm.mHandler.postDelayed(() -> {
+ if (proc != null) {
+ proc.removeAllowBackgroundActivityStartsToken(r);
+ }
+ }, delayMillis);
+ }
+
private boolean requestStartTargetPermissionsReviewIfNeededLocked(ServiceRecord r,
String callingPackage, int callingUid, Intent service, boolean callerFg,
final int userId) {
@@ -752,6 +781,9 @@ public final class ActiveServices {
if (r.record != null) {
final long origId = Binder.clearCallingIdentity();
try {
+ // immediately remove bg activity whitelisting token if there was one
+ removeAllowBackgroundActivityStartsServiceToken(callerApp, r.record,
+ 0 /* delayMillis */);
stopServiceLocked(r.record);
} finally {
Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index bb239acb5c60..26141f7d7066 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19495,8 +19495,8 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
- boolean fgRequired, String callingPackage, int userId)
- throws TransactionTooLargeException {
+ boolean fgRequired, String callingPackage, int userId,
+ boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
synchronized(ActivityManagerService.this) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startServiceInPackage: " + service + " type=" + resolvedType);
@@ -19504,7 +19504,8 @@ public class ActivityManagerService extends IActivityManager.Stub
ComponentName res;
try {
res = mServices.startServiceLocked(null, service,
- resolvedType, -1, uid, fgRequired, callingPackage, userId);
+ resolvedType, -1, uid, fgRequired, callingPackage, userId,
+ allowBackgroundActivityStarts);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index b675d9d4f9cf..98c9ad66bc5c 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -51,6 +51,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
public static final int FLAG_ACTIVITY_SENDER = 1 << 0;
public static final int FLAG_BROADCAST_SENDER = 1 << 1;
+ public static final int FLAG_SERVICE_SENDER = 1 << 2;
final PendingIntentController controller;
final Key key;
@@ -62,6 +63,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
private RemoteCallbackList<IResultReceiver> mCancelCallbacks;
private ArraySet<IBinder> mAllowBgActivityStartsForActivitySender = new ArraySet<>();
private ArraySet<IBinder> mAllowBgActivityStartsForBroadcastSender = new ArraySet<>();
+ private ArraySet<IBinder> mAllowBgActivityStartsForServiceSender = new ArraySet<>();
String stringName;
String lastTagPrefix;
@@ -228,6 +230,9 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
if ((flags & FLAG_BROADCAST_SENDER) != 0) {
mAllowBgActivityStartsForBroadcastSender.add(token);
}
+ if ((flags & FLAG_SERVICE_SENDER) != 0) {
+ mAllowBgActivityStartsForServiceSender.add(token);
+ }
}
public void registerCancelListenerLocked(IResultReceiver receiver) {
@@ -426,7 +431,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
try {
controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType,
key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
- key.packageName, userId);
+ key.packageName, userId,
+ mAllowBgActivityStartsForServiceSender.contains(whitelistToken));
} catch (RuntimeException e) {
Slog.w(TAG, "Unable to send startService intent", e);
} catch (TransactionTooLargeException e) {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 0d0824a74cdd..054c83080d98 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1142,11 +1142,13 @@ final class ProcessRecord implements WindowProcessListener {
}
void addAllowBackgroundActivityStartsToken(Binder entity) {
+ if (entity == null) return;
mAllowBackgroundActivityStartsTokens.add(entity);
mWindowProcessController.setAllowBackgroundActivityStarts(true);
}
void removeAllowBackgroundActivityStartsToken(Binder entity) {
+ if (entity == null) return;
mAllowBackgroundActivityStartsTokens.remove(entity);
mWindowProcessController.setAllowBackgroundActivityStarts(
!mAllowBackgroundActivityStartsTokens.isEmpty());
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c68e0f98325e..7ecdad27c505 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -77,6 +77,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
+import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG_CRITICAL;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL;
@@ -4452,7 +4453,8 @@ public class NotificationManagerService extends SystemService {
am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(),
WHITELIST_TOKEN, duration);
am.setPendingIntentAllowBgActivityStarts(pendingIntent.getTarget(),
- WHITELIST_TOKEN, (FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER));
+ WHITELIST_TOKEN, (FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER
+ | FLAG_SERVICE_SENDER));
}
}
}