Limit the number of attempts to launch bad content providers
Previously if a content provider gets killed/exits by itself during launching, the system would keep retrying to launch it; now limit the maximum attempts to 3 and give up after that. Bug: 141020060 Test: atest CtsAppTestCases:BadProviderTest Change-Id: Idcc308c2761c444b62c0edf377c78622dd1c39b5
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user