summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jing Ji <jji@google.com> 2019-10-03 00:08:46 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-10-03 00:08:46 +0000
commit4ba39391c8356816f2c215aabf6d6ebfa6df62cc (patch)
treeabbd1d6705873d86c4418c8f3d4353ea27a3b5d5
parent01e165a9ef98f11b23c180ab482dde192d3e013c (diff)
parent29b5b9e229e72038f02a9a01bade5aaf8ec129d0 (diff)
Merge "Limit the number of attempts to launch bad content providers"
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java20
-rw-r--r--services/core/java/com/android/server/am/ContentProviderRecord.java4
2 files changed, 23 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 71ff60720489..ee98af4020ad 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7441,6 +7441,7 @@ public class ActivityManagerService extends IActivityManager.Stub
dst.setProcess(r);
dst.notifyAll();
}
+ dst.mRestartCount = 0;
updateOomAdjLocked(r, true, OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER);
maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
src.info.authority);
@@ -13884,9 +13885,20 @@ public class ActivityManagerService extends IActivityManager.Stub
return false;
}
+ /**
+ * Remove the dying provider from known provider map and launching provider map.
+ * @param proc The dying process recoder
+ * @param cpr The provider to be removed.
+ * @param always If true, remove the provider from launching map always, no more restart attempt
+ * @return true if the given provider is in launching
+ */
private final boolean removeDyingProviderLocked(ProcessRecord proc,
ContentProviderRecord cpr, boolean always) {
- final boolean inLaunching = mLaunchingProviders.contains(cpr);
+ boolean inLaunching = mLaunchingProviders.contains(cpr);
+ if (inLaunching && !always && ++cpr.mRestartCount > ContentProviderRecord.MAX_RETRY_COUNT) {
+ // It's being launched but we've reached maximum attempts, force the removal
+ always = true;
+ }
if (!inLaunching || always) {
synchronized (cpr) {
@@ -13938,6 +13950,8 @@ public class ActivityManagerService extends IActivityManager.Stub
if (inLaunching && always) {
mLaunchingProviders.remove(cpr);
+ cpr.mRestartCount = 0;
+ inLaunching = false;
}
return inLaunching;
}
@@ -14153,6 +14167,10 @@ public class ActivityManagerService extends IActivityManager.Stub
for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
ContentProviderRecord cpr = mLaunchingProviders.get(i);
if (cpr.launchingApp == app) {
+ if (++cpr.mRestartCount > ContentProviderRecord.MAX_RETRY_COUNT) {
+ // It's being launched but we've reached maximum attempts, mark it as bad
+ alwaysBad = true;
+ }
if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
restart = true;
} else {
diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java
index 46dfc7c60fd9..d8d8cccc05f3 100644
--- a/services/core/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/core/java/com/android/server/am/ContentProviderRecord.java
@@ -38,6 +38,9 @@ import java.io.PrintWriter;
import java.util.ArrayList;
final class ContentProviderRecord implements ComponentName.WithComponentName {
+ // Maximum attempts to bring up the content provider before giving up.
+ static final int MAX_RETRY_COUNT = 3;
+
final ActivityManagerService service;
public final ProviderInfo info;
final int uid;
@@ -54,6 +57,7 @@ final class ContentProviderRecord implements ComponentName.WithComponentName {
ArrayMap<IBinder, ExternalProcessHandle> externalProcessTokenToHandle;
// Count for external process for which we have no handles.
int externalProcessNoHandleCount;
+ int mRestartCount; // number of times we tried before bringing up it successfully.
ProcessRecord proc; // if non-null, hosting process.
ProcessRecord launchingApp; // if non-null, waiting for this app to be launched.
String stringName;