From 09c916bccbf236ccd0a2c80941e28cc55006e02a Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 8 Dec 2009 14:50:51 -0800 Subject: [PATCH] Add bindService API to not bring ot foreground. Add a new flag for bindService that tells the system to not bring the target service's process in to the foreground scheduling class. This is used by the sync system to not cause the current sync adapter to come to the foreground as it is running. Also some small improvements to the debug output of the process list of oom adj and scheduling info. --- api/current.xml | 11 ++ core/java/android/content/Context.java | 12 ++ core/java/android/content/SyncManager.java | 5 +- .../server/am/ActivityManagerService.java | 119 +++++++++++++++--- 4 files changed, 127 insertions(+), 20 deletions(-) diff --git a/api/current.xml b/api/current.xml index a5d1967a3baff..af9c67d06ebb5 100644 --- a/api/current.xml +++ b/api/current.xml @@ -32352,6 +32352,17 @@ visibility="public" > + + = EMPTY_APP_ADJ) { + oomAdj = buildOomTag("empty", null, r.setAdj, + EMPTY_APP_ADJ); + } else if (r.setAdj >= CONTENT_PROVIDER_ADJ) { + oomAdj = buildOomTag("cprov", null, r.setAdj, + CONTENT_PROVIDER_ADJ); + } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) { + oomAdj = buildOomTag("hid", " ", r.setAdj, + HIDDEN_APP_MIN_ADJ); + } else if (r.setAdj >= service.HOME_APP_ADJ) { + oomAdj = buildOomTag("home ", null, r.setAdj, + service.HOME_APP_ADJ); + } else if (r.setAdj >= service.SECONDARY_SERVER_ADJ) { + oomAdj = buildOomTag("svc", " ", r.setAdj, + service.SECONDARY_SERVER_ADJ); + } else if (r.setAdj >= service.BACKUP_APP_ADJ) { + oomAdj = buildOomTag("bckup", null, r.setAdj, + service.BACKUP_APP_ADJ); + } else if (r.setAdj >= service.VISIBLE_APP_ADJ) { + oomAdj = buildOomTag("vis ", null, r.setAdj, + service.VISIBLE_APP_ADJ); + } else if (r.setAdj >= service.FOREGROUND_APP_ADJ) { + oomAdj = buildOomTag("fore ", null, r.setAdj, + service.FOREGROUND_APP_ADJ); + } else if (r.setAdj >= CORE_SERVER_ADJ) { + oomAdj = buildOomTag("core ", null, r.setAdj, + CORE_SERVER_ADJ); + } else if (r.setAdj >= SYSTEM_ADJ) { + oomAdj = buildOomTag("sys ", null, r.setAdj, + SYSTEM_ADJ); + } else { + oomAdj = Integer.toString(r.setAdj); + } + String schedGroup; + switch (r.setSchedGroup) { + case Process.THREAD_GROUP_BG_NONINTERACTIVE: + schedGroup = "B"; + break; + case Process.THREAD_GROUP_DEFAULT: + schedGroup = "F"; + break; + default: + schedGroup = Integer.toString(r.setSchedGroup); + break; + } + pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)", prefix, (r.persistent ? persistentLabel : normalLabel), - i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType)); + i, oomAdj, schedGroup, r.toString(), r.adjType)); if (r.adjSource != null || r.adjTarget != null) { pw.println(prefix + " " + r.adjTarget + " used by " + r.adjSource); @@ -13038,6 +13094,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (app.thread == null) { app.adjSeq = mAdjSeq; + app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; return (app.curAdj=EMPTY_APP_ADJ); } @@ -13058,52 +13115,63 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // Determine the importance of the process, starting with most // important to least, and assign an appropriate OOM adjustment. int adj; + int schedGroup; int N; if (app == TOP_APP) { // The last app on the list is the foreground app. adj = FOREGROUND_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "top-activity"; } else if (app.instrumentationClass != null) { // Don't want to kill running instrumentation. adj = FOREGROUND_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "instrumentation"; } else if (app.persistentActivities > 0) { // Special persistent activities... shouldn't be used these days. adj = FOREGROUND_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "persistent"; } else if (app.curReceiver != null || (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { // An app that is currently receiving a broadcast also // counts as being in the foreground. adj = FOREGROUND_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "broadcast"; } else if (app.executingServices.size() > 0) { // An app that is currently executing a service callback also // counts as being in the foreground. adj = FOREGROUND_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "exec-service"; } else if (app.foregroundServices) { // The user is aware of this app, so make it visible. adj = VISIBLE_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "foreground-service"; } else if (app.forcingToForeground != null) { // The user is aware of this app, so make it visible. adj = VISIBLE_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "force-foreground"; app.adjSource = app.forcingToForeground; } else if (app == mHomeProcess) { // This process is hosting what we currently consider to be the // home app, so we don't want to let it go into the background. adj = HOME_APP_ADJ; + schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; app.adjType = "home"; } else if ((N=app.activities.size()) != 0) { // This app is in the background with paused activities. adj = hiddenAdj; + schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; app.adjType = "bg-activities"; for (int j=0; j FOREGROUND_APP_ADJ) { + if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ + || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { final long now = SystemClock.uptimeMillis(); // This process is more important if the top activity is // bound to the service. @@ -13149,7 +13218,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } } - if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) { + if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ + || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { Iterator kt = s.connections.values().iterator(); while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { @@ -13181,6 +13251,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen app.adjSource = cr.binding.client; app.adjTarget = s.serviceInfo.name; } + if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { + if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { + schedGroup = Process.THREAD_GROUP_DEFAULT; + } + } } HistoryRecord a = cr.activity; //if (a != null) { @@ -13190,6 +13265,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen (a.state == ActivityState.RESUMED || a.state == ActivityState.PAUSING)) { adj = FOREGROUND_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "service"; app.adjTypeCode = ActivityManager.RunningAppProcessInfo .REASON_SERVICE_IN_USE; @@ -13211,9 +13287,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } - if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) { + if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ + || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { Iterator jt = app.pubProviders.values().iterator(); - while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { + while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ + || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { ContentProviderRecord cpr = (ContentProviderRecord)jt.next(); if (cpr.clients.size() != 0) { Iterator kt = cpr.clients.iterator(); @@ -13242,6 +13320,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen app.adjSource = client; app.adjTarget = cpr.info.name; } + if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { + schedGroup = Process.THREAD_GROUP_DEFAULT; + } } } // If the provider has external (non-framework) process @@ -13250,6 +13331,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (cpr.externals != 0) { if (adj > FOREGROUND_APP_ADJ) { adj = FOREGROUND_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "provider"; app.adjTarget = cpr.info.name; } @@ -13272,12 +13354,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); if (adj > app.maxAdj) { adj = app.maxAdj; + if (app.maxAdj <= VISIBLE_APP_ADJ) { + schedGroup = Process.THREAD_GROUP_DEFAULT; + } } app.curAdj = adj; - app.curSchedGroup = adj > VISIBLE_APP_ADJ - ? Process.THREAD_GROUP_BG_NONINTERACTIVE - : Process.THREAD_GROUP_DEFAULT; + app.curSchedGroup = schedGroup; return adj; } @@ -13422,7 +13505,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP); - if (app.pid != 0 && app.pid != MY_PID) { + if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) { if (app.curRawAdj != app.setRawAdj) { if (app.curRawAdj > FOREGROUND_APP_ADJ && app.setRawAdj <= FOREGROUND_APP_ADJ) {