diff options
| author | 2019-10-03 00:08:46 +0000 | |
|---|---|---|
| committer | 2019-10-03 00:08:46 +0000 | |
| commit | 4ba39391c8356816f2c215aabf6d6ebfa6df62cc (patch) | |
| tree | abbd1d6705873d86c4418c8f3d4353ea27a3b5d5 | |
| parent | 01e165a9ef98f11b23c180ab482dde192d3e013c (diff) | |
| parent | 29b5b9e229e72038f02a9a01bade5aaf8ec129d0 (diff) | |
Merge "Limit the number of attempts to launch bad content providers"
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 20 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ContentProviderRecord.java | 4 | 
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;  |