diff options
author | riddle_hsu <riddle_hsu@htc.com> | 2015-04-16 11:36:23 +0800 |
---|---|---|
committer | riddle_hsu <riddle_hsu@htc.com> | 2015-04-16 11:36:23 +0800 |
commit | 239d17c05a2694d4c415cb48adeb39e4e3dd386d (patch) | |
tree | 2c375affee3c82a5b86d03c11e64d29fc178d30f /services | |
parent | 150e0e87e1faa01f927cfe8c7110ef843612a1df (diff) | |
download | frameworks_base-239d17c05a2694d4c415cb48adeb39e4e3dd386d.zip frameworks_base-239d17c05a2694d4c415cb48adeb39e4e3dd386d.tar.gz frameworks_base-239d17c05a2694d4c415cb48adeb39e4e3dd386d.tar.bz2 |
[ActivityManager] Avoid unnecessary restart provider process
Caller C accesses provider P. Both processes of C and P died
before P publishes, P will still be restarted even there is
no connection because P is in mLaunchingProviders.
When device is low memory, the restarting provider process
may be killed easily before publish because no caller to raise
its oom-adj. Then device will busy keeping restart it.
Solution:
If there is no connection to the provider, do not restart it.
Change-Id: If6f2d2258d78b6c0989c6e5f3e0cad14db821464
Diffstat (limited to 'services')
-rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 05a4d7e..a5cd1db 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -14891,7 +14891,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } - for (int i=0; i<cpr.connections.size(); i++) { + for (int i = cpr.connections.size() - 1; i >= 0; i--) { ContentProviderConnection conn = cpr.connections.get(i); if (conn.waiting) { // If this connection is waiting for the provider, then we don't @@ -14983,10 +14983,11 @@ public final class ActivityManagerService extends ActivityManagerNative boolean restart = false; // Remove published content providers. - for (int i=app.pubProviders.size()-1; i>=0; i--) { + for (int i = app.pubProviders.size() - 1; i >= 0; i--) { ContentProviderRecord cpr = app.pubProviders.valueAt(i); final boolean always = app.bad || !allowRestart; - if (removeDyingProviderLocked(app, cpr, always) || always) { + boolean inLaunching = removeDyingProviderLocked(app, cpr, always); + if ((inLaunching || always) && !cpr.connections.isEmpty()) { // We left the provider in the launching list, need to // restart it. restart = true; @@ -15004,7 +15005,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Unregister from connected content providers. if (!app.conProviders.isEmpty()) { - for (int i=0; i<app.conProviders.size(); i++) { + for (int i = app.conProviders.size() - 1; i >= 0; i--) { ContentProviderConnection conn = app.conProviders.get(i); conn.provider.connections.remove(conn); stopAssociationLocked(app.uid, app.processName, conn.provider.uid, @@ -15019,9 +15020,8 @@ public final class ActivityManagerService extends ActivityManagerNative // XXX Commented out for now. Trying to figure out a way to reproduce // the actual situation to identify what is actually going on. if (false) { - for (int i=0; i<mLaunchingProviders.size(); i++) { - ContentProviderRecord cpr = (ContentProviderRecord) - mLaunchingProviders.get(i); + for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { + ContentProviderRecord cpr = mLaunchingProviders.get(i); if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { synchronized (cpr) { cpr.launchingApp = null; @@ -15034,7 +15034,7 @@ public final class ActivityManagerService extends ActivityManagerNative skipCurrentReceiverLocked(app); // Unregister any receivers. - for (int i=app.receivers.size()-1; i>=0; i--) { + for (int i = app.receivers.size() - 1; i >= 0; i--) { removeReceiverLocked(app.receivers.valueAt(i)); } app.receivers.clear(); @@ -15052,7 +15052,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } - for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { + for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) { ProcessChangeItem item = mPendingProcessChanges.get(i); if (item.pid == app.pid) { mPendingProcessChanges.remove(i); @@ -15127,18 +15127,14 @@ public final class ActivityManagerService extends ActivityManagerNative // and if any run in this process then either schedule a restart of // the process or kill the client waiting for it if this process has // gone bad. - int NL = mLaunchingProviders.size(); boolean restart = false; - for (int i=0; i<NL; i++) { + for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { ContentProviderRecord cpr = mLaunchingProviders.get(i); if (cpr.launchingApp == app) { - if (!alwaysBad && !app.bad) { + if (!alwaysBad && !app.bad && !cpr.connections.isEmpty()) { restart = true; } else { removeDyingProviderLocked(app, cpr, true); - // cpr should have been removed from mLaunchingProviders - NL = mLaunchingProviders.size(); - i--; } } } |