diff options
Diffstat (limited to 'services/java/com/android')
8 files changed, 499 insertions, 457 deletions
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java index fa758a8..bc06561 100644 --- a/services/java/com/android/server/AlarmManagerService.java +++ b/services/java/com/android/server/AlarmManagerService.java @@ -351,12 +351,11 @@ class AlarmManagerService extends IAlarmManager.Stub { } // iterator over the list removing any it where the intent match - Iterator<Alarm> it = alarmList.iterator(); - - while (it.hasNext()) { - Alarm alarm = it.next(); + for (int i=0; i<alarmList.size(); i++) { + Alarm alarm = alarmList.get(i); if (alarm.operation.equals(operation)) { - it.remove(); + alarmList.remove(i); + i--; } } } @@ -375,12 +374,11 @@ class AlarmManagerService extends IAlarmManager.Stub { } // iterator over the list removing any it where the intent match - Iterator<Alarm> it = alarmList.iterator(); - - while (it.hasNext()) { - Alarm alarm = it.next(); + for (int i=0; i<alarmList.size(); i++) { + Alarm alarm = alarmList.get(i); if (alarm.operation.getTargetPackage().equals(packageName)) { - it.remove(); + alarmList.remove(i); + i--; } } } @@ -398,12 +396,11 @@ class AlarmManagerService extends IAlarmManager.Stub { } // iterator over the list removing any it where the intent match - Iterator<Alarm> it = alarmList.iterator(); - - while (it.hasNext()) { - Alarm alarm = it.next(); + for (int i=0; i<alarmList.size(); i++) { + Alarm alarm = alarmList.get(i); if (UserHandle.getUserId(alarm.operation.getCreatorUid()) == userHandle) { - it.remove(); + alarmList.remove(i); + i--; } } } @@ -666,12 +663,10 @@ class AlarmManagerService extends IAlarmManager.Stub { ArrayList<Alarm> triggerList, long now) { - Iterator<Alarm> it = alarmList.iterator(); - ArrayList<Alarm> repeats = new ArrayList<Alarm>(); - - while (it.hasNext()) - { - Alarm alarm = it.next(); + ArrayList<Alarm> repeats = null; + + for (int i=0; i<alarmList.size(); i++) { + Alarm alarm = alarmList.get(i); if (localLOGV) Slog.v(TAG, "Checking active alarm when=" + alarm.when + " " + alarm); @@ -702,20 +697,25 @@ class AlarmManagerService extends IAlarmManager.Stub { triggerList.add(alarm); // remove the alarm from the list - it.remove(); - + alarmList.remove(i); + i--; + // if it repeats queue it up to be read-added to the list if (alarm.repeatInterval > 0) { + if (repeats == null) { + repeats = new ArrayList<Alarm>(); + } repeats.add(alarm); } } // reset any repeating alarms. - it = repeats.iterator(); - while (it.hasNext()) { - Alarm alarm = it.next(); - alarm.when += alarm.count * alarm.repeatInterval; - addAlarmLocked(alarm); + if (repeats != null) { + for (int i=0; i<repeats.size(); i++) { + Alarm alarm = repeats.get(i); + alarm.when += alarm.count * alarm.repeatInterval; + addAlarmLocked(alarm); + } } if (alarmList.size() > 0) { @@ -785,12 +785,14 @@ class AlarmManagerService extends IAlarmManager.Stub { public void run() { + ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); + while (true) { int result = waitForAlarm(mDescriptor); - - ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); - + + triggerList.clear(); + if ((result & TIME_CHANGED_MASK) != 0) { remove(mTimeTickSender); mClockReceiver.scheduleTimeTickEvent(); @@ -820,9 +822,8 @@ class AlarmManagerService extends IAlarmManager.Stub { triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowELAPSED); // now trigger the alarms - Iterator<Alarm> it = triggerList.iterator(); - while (it.hasNext()) { - Alarm alarm = it.next(); + for (int i=0; i<triggerList.size(); i++) { + Alarm alarm = triggerList.get(i); try { if (localLOGV) Slog.v(TAG, "sending alarm " + alarm); alarm.operation.send(mContext, 0, @@ -913,10 +914,8 @@ class AlarmManagerService extends IAlarmManager.Stub { } // now trigger the alarms without the lock held - Iterator<Alarm> it = triggerList.iterator(); - while (it.hasNext()) - { - Alarm alarm = it.next(); + for (int i=0; i<triggerList.size(); i++) { + Alarm alarm = triggerList.get(i); try { alarm.operation.send(); } catch (PendingIntent.CanceledException e) { diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java index 10db70f..84e44bd 100644 --- a/services/java/com/android/server/am/ActiveServices.java +++ b/services/java/com/android/server/am/ActiveServices.java @@ -574,30 +574,26 @@ public class ActiveServices { b.binder = service; b.requested = true; b.received = true; - if (r.connections.size() > 0) { - Iterator<ArrayList<ConnectionRecord>> it - = r.connections.values().iterator(); - while (it.hasNext()) { - ArrayList<ConnectionRecord> clist = it.next(); - for (int i=0; i<clist.size(); i++) { - ConnectionRecord c = clist.get(i); - if (!filter.equals(c.binding.intent.intent)) { - if (DEBUG_SERVICE) Slog.v( - TAG, "Not publishing to: " + c); - if (DEBUG_SERVICE) Slog.v( - TAG, "Bound intent: " + c.binding.intent.intent); - if (DEBUG_SERVICE) Slog.v( - TAG, "Published intent: " + intent); - continue; - } - if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); - try { - c.conn.connected(r.name, service); - } catch (Exception e) { - Slog.w(TAG, "Failure sending service " + r.name + - " to connection " + c.conn.asBinder() + - " (in " + c.binding.client.processName + ")", e); - } + for (int conni=r.connections.size()-1; conni>=0; conni--) { + ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni); + for (int i=0; i<clist.size(); i++) { + ConnectionRecord c = clist.get(i); + if (!filter.equals(c.binding.intent.intent)) { + if (DEBUG_SERVICE) Slog.v( + TAG, "Not publishing to: " + c); + if (DEBUG_SERVICE) Slog.v( + TAG, "Bound intent: " + c.binding.intent.intent); + if (DEBUG_SERVICE) Slog.v( + TAG, "Published intent: " + intent); + continue; + } + if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); + try { + c.conn.connected(r.name, service); + } catch (Exception e) { + Slog.w(TAG, "Failure sending service " + r.name + + " to connection " + c.conn.asBinder() + + " (in " + c.binding.client.processName + ")", e); } } } @@ -1064,10 +1060,9 @@ public class ActiveServices { } private final void requestServiceBindingsLocked(ServiceRecord r) { - Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); - while (bindings.hasNext()) { - IntentBindRecord i = bindings.next(); - if (!requestServiceBindingLocked(r, i, false)) { + for (int i=r.bindings.size()-1; i>=0; i--) { + IntentBindRecord ibr = r.bindings.valueAt(i); + if (!requestServiceBindingLocked(r, ibr, false)) { break; } } @@ -1179,50 +1174,45 @@ public class ActiveServices { if (!force && r.startRequested) { return; } - if (r.connections.size() > 0) { - if (!force) { - // XXX should probably keep a count of the number of auto-create - // connections directly in the service. - Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); - while (it.hasNext()) { - ArrayList<ConnectionRecord> cr = it.next(); - for (int i=0; i<cr.size(); i++) { - if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { - return; - } + if (!force) { + // XXX should probably keep a count of the number of auto-create + // connections directly in the service. + for (int conni=r.connections.size()-1; conni>=0; conni--) { + ArrayList<ConnectionRecord> cr = r.connections.valueAt(conni); + for (int i=0; i<cr.size(); i++) { + if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { + return; } } } + } - // Report to all of the connections that the service is no longer - // available. - Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); - while (it.hasNext()) { - ArrayList<ConnectionRecord> c = it.next(); - for (int i=0; i<c.size(); i++) { - ConnectionRecord cr = c.get(i); - // There is still a connection to the service that is - // being brought down. Mark it as dead. - cr.serviceDead = true; - try { - cr.conn.connected(r.name, null); - } catch (Exception e) { - Slog.w(TAG, "Failure disconnecting service " + r.name + - " to connection " + c.get(i).conn.asBinder() + - " (in " + c.get(i).binding.client.processName + ")", e); - } + // Report to all of the connections that the service is no longer + // available. + for (int conni=r.connections.size()-1; conni>=0; conni--) { + ArrayList<ConnectionRecord> c = r.connections.valueAt(conni); + for (int i=0; i<c.size(); i++) { + ConnectionRecord cr = c.get(i); + // There is still a connection to the service that is + // being brought down. Mark it as dead. + cr.serviceDead = true; + try { + cr.conn.connected(r.name, null); + } catch (Exception e) { + Slog.w(TAG, "Failure disconnecting service " + r.name + + " to connection " + c.get(i).conn.asBinder() + + " (in " + c.get(i).binding.client.processName + ")", e); } } } // Tell the service that it has been unbound. - if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { - Iterator<IntentBindRecord> it = r.bindings.values().iterator(); - while (it.hasNext()) { - IntentBindRecord ibr = it.next(); + if (r.app != null && r.app.thread != null) { + for (int i=r.bindings.size()-1; i>=0; i--) { + IntentBindRecord ibr = r.bindings.valueAt(i); if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr + ": hasBound=" + ibr.hasBound); - if (r.app != null && r.app.thread != null && ibr.hasBound) { + if (ibr.hasBound) { try { bumpServiceExecutingLocked(r, "bring down unbind"); mAm.updateOomAdjLocked(r.app); @@ -1595,22 +1585,18 @@ public class ActiveServices { Iterator<ServiceRecord> it = app.services.iterator(); while (it.hasNext()) { ServiceRecord r = it.next(); - if (r.connections.size() > 0) { - Iterator<ArrayList<ConnectionRecord>> jt - = r.connections.values().iterator(); - while (jt.hasNext()) { - ArrayList<ConnectionRecord> cl = jt.next(); - for (int i=0; i<cl.size(); i++) { - ConnectionRecord c = cl.get(i); - if (c.binding.client != app) { - try { - //c.conn.connected(r.className, null); - } catch (Exception e) { - // todo: this should be asynchronous! - Slog.w(TAG, "Exception thrown disconnected servce " - + r.shortName - + " from app " + app.processName, e); - } + for (int conni=r.connections.size()-1; conni>=0; conni--) { + ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni); + for (int i=0; i<cl.size(); i++) { + ConnectionRecord c = cl.get(i); + if (c.binding.client != app) { + try { + //c.conn.connected(r.className, null); + } catch (Exception e) { + // todo: this should be asynchronous! + Slog.w(TAG, "Exception thrown disconnected servce " + + r.shortName + + " from app " + app.processName, e); } } } @@ -1645,17 +1631,13 @@ public class ActiveServices { if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); } - boolean hasClients = sr.bindings.size() > 0; - if (hasClients) { - Iterator<IntentBindRecord> bindings - = sr.bindings.values().iterator(); - while (bindings.hasNext()) { - IntentBindRecord b = bindings.next(); - if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b - + ": shouldUnbind=" + b.hasBound); - b.binder = null; - b.requested = b.received = b.hasBound = false; - } + final int numClients = sr.bindings.size(); + for (int bindingi=numClients-1; bindingi>=0; bindingi--) { + IntentBindRecord b = sr.bindings.valueAt(bindingi); + if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b + + ": shouldUnbind=" + b.hasBound); + b.binder = null; + b.requested = b.received = b.hasBound = false; } if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags @@ -1676,7 +1658,7 @@ public class ActiveServices { if (sr.startRequested && (sr.stopIfKilled || canceled)) { if (sr.pendingStarts.size() == 0) { sr.startRequested = false; - if (!hasClients) { + if (numClients > 0) { // Whoops, no reason to restart! bringDownServiceLocked(sr, true); } @@ -1732,7 +1714,8 @@ public class ActiveServices { info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; } - for (ArrayList<ConnectionRecord> connl : r.connections.values()) { + for (int conni=r.connections.size()-1; conni>=0; conni--) { + ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni); for (int i=0; i<connl.size(); i++) { ConnectionRecord conn = connl.get(i); if (conn.clientLabel != 0) { @@ -1805,7 +1788,8 @@ public class ActiveServices { int userId = UserHandle.getUserId(Binder.getCallingUid()); ServiceRecord r = mServiceMap.getServiceByName(name, userId); if (r != null) { - for (ArrayList<ConnectionRecord> conn : r.connections.values()) { + for (int conni=r.connections.size()-1; conni>=0; conni--) { + ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni); for (int i=0; i<conn.size(); i++) { if (conn.get(i).clientIntent != null) { return conn.get(i).clientIntent; @@ -1859,6 +1843,7 @@ public class ActiveServices { boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { boolean needSep = false; + boolean needSepResult = false; ItemMatcher matcher = new ItemMatcher(); matcher.build(args, opti); @@ -1881,6 +1866,7 @@ public class ActiveServices { if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { continue; } + needSepResult = true; if (!printed) { if (user != 0) { pw.println(); @@ -1907,7 +1893,8 @@ public class ActiveServices { pw.println(r.connections.size()); if (r.connections.size() > 0) { pw.println(" Connections:"); - for (ArrayList<ConnectionRecord> clist : r.connections.values()) { + for (int conni=0; conni<=r.connections.size(); conni++) { + ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni); for (int i = 0; i < clist.size(); i++) { ConnectionRecord conn = clist.get(i); pw.print(" "); @@ -1960,6 +1947,7 @@ public class ActiveServices { if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { continue; } + needSepResult = true; if (!printed) { if (needSep) pw.println(" "); needSep = true; @@ -1982,6 +1970,7 @@ public class ActiveServices { if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { continue; } + needSepResult = true; if (!printed) { if (needSep) pw.println(" "); needSep = true; @@ -2004,6 +1993,7 @@ public class ActiveServices { if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { continue; } + needSepResult = true; if (!printed) { if (needSep) pw.println(" "); needSep = true; @@ -2032,6 +2022,7 @@ public class ActiveServices { || !dumpPackage.equals(cr.binding.client.info.packageName))) { continue; } + needSepResult = true; if (!printed) { if (needSep) pw.println(" "); needSep = true; @@ -2042,11 +2033,10 @@ public class ActiveServices { cr.dump(pw, " "); } } - needSep = true; } } - return needSep; + return needSepResult; } /** diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 86a6bca..8d71cf9 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -6515,6 +6515,7 @@ public final class ActivityManagerService extends ActivityManagerNative int userId = app.userId; if (providers != null) { int N = providers.size(); + app.pubProviders.ensureCapacity(N + app.pubProviders.size()); for (int i=0; i<N; i++) { ProviderInfo cpi = (ProviderInfo)providers.get(i); @@ -10099,6 +10100,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage) { + boolean dumpedHeader = false; boolean needSep = false; boolean onlyHistory = false; @@ -10194,14 +10196,14 @@ public final class ActivityManagerService extends ActivityManagerNative boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage) { - boolean needSep = true; + boolean needSep; ItemMatcher matcher = new ItemMatcher(); matcher.build(args, opti); pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); - mProviderMap.dumpProvidersLocked(pw, dumpAll); + needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); if (mLaunchingProviders.size() > 0) { boolean printed = false; @@ -10222,13 +10224,28 @@ public final class ActivityManagerService extends ActivityManagerNative } if (mGrantedUriPermissions.size() > 0) { - if (needSep) pw.println(); - needSep = true; - pw.println("Granted Uri Permissions:"); + boolean printed = false; + int dumpUid = -1; + if (dumpPackage != null) { + try { + dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); + } catch (NameNotFoundException e) { + dumpUid = -1; + } + } for (int i=0; i<mGrantedUriPermissions.size(); i++) { int uid = mGrantedUriPermissions.keyAt(i); + if (dumpUid >= 0 && UserHandle.getAppId(uid) != dumpUid) { + continue; + } HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); + if (!printed) { + if (needSep) pw.println(); + needSep = true; + pw.println(" Granted Uri Permissions:"); + printed = true; + } pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); for (UriPermission perm : perms.values()) { @@ -10238,7 +10255,6 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - needSep = true; } return needSep; @@ -11025,24 +11041,20 @@ public final class ActivityManagerService extends ActivityManagerNative boolean restart = false; // Remove published content providers. - if (!app.pubProviders.isEmpty()) { - Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); - while (it.hasNext()) { - ContentProviderRecord cpr = it.next(); - - final boolean always = app.bad || !allowRestart; - if (removeDyingProviderLocked(app, cpr, always) || always) { - // We left the provider in the launching list, need to - // restart it. - restart = true; - } - - cpr.provider = null; - cpr.proc = null; + 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) { + // We left the provider in the launching list, need to + // restart it. + restart = true; } - app.pubProviders.clear(); + + cpr.provider = null; + cpr.proc = null; } - + app.pubProviders.clear(); + // Take care of any launching providers waiting for this process. if (checkAppInLaunchingProvidersLocked(app, false)) { restart = true; @@ -13119,158 +13131,159 @@ public final class ActivityManagerService extends ActivityManagerNative // has said it is doing work. app.keeping = true; } - if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ - || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { - Iterator<ArrayList<ConnectionRecord>> kt - = s.connections.values().iterator(); - while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { - ArrayList<ConnectionRecord> clist = kt.next(); - for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { - // XXX should compute this based on the max of - // all connected clients. - ConnectionRecord cr = clist.get(i); - if (cr.binding.client == app) { - // Binding to ourself is not interesting. - continue; + for (int conni = s.connections.size()-1; + conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ + || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); + conni--) { + ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); + for (int i = 0; + i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ + || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); + i++) { + // XXX should compute this based on the max of + // all connected clients. + ConnectionRecord cr = clist.get(i); + if (cr.binding.client == app) { + // Binding to ourself is not interesting. + continue; + } + if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { + ProcessRecord client = cr.binding.client; + int clientAdj = adj; + int myHiddenAdj = hiddenAdj; + if (myHiddenAdj > client.hiddenAdj) { + if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { + myHiddenAdj = client.hiddenAdj; + } else { + myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; + } } - if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { - ProcessRecord client = cr.binding.client; - int clientAdj = adj; - int myHiddenAdj = hiddenAdj; - if (myHiddenAdj > client.hiddenAdj) { - if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { - myHiddenAdj = client.hiddenAdj; - } else { - myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; - } + int myClientHiddenAdj = clientHiddenAdj; + if (myClientHiddenAdj > client.clientHiddenAdj) { + if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { + myClientHiddenAdj = client.clientHiddenAdj; + } else { + myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; } - int myClientHiddenAdj = clientHiddenAdj; - if (myClientHiddenAdj > client.clientHiddenAdj) { - if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { - myClientHiddenAdj = client.clientHiddenAdj; - } else { - myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ; - } + } + int myEmptyAdj = emptyAdj; + if (myEmptyAdj > client.emptyAdj) { + if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { + myEmptyAdj = client.emptyAdj; + } else { + myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; } - int myEmptyAdj = emptyAdj; - if (myEmptyAdj > client.emptyAdj) { - if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { - myEmptyAdj = client.emptyAdj; - } else { - myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; + } + clientAdj = computeOomAdjLocked(client, myHiddenAdj, + myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); + String adjType = null; + if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { + // Not doing bind OOM management, so treat + // this guy more like a started service. + if (app.hasShownUi && app != mHomeProcess) { + // If this process has shown some UI, let it immediately + // go to the LRU list because it may be pretty heavy with + // UI stuff. We'll tag it with a label just to help + // debug and understand what is going on. + if (adj > clientAdj) { + adjType = "bound-bg-ui-services"; } - } - clientAdj = computeOomAdjLocked(client, myHiddenAdj, - myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); - String adjType = null; - if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { - // Not doing bind OOM management, so treat - // this guy more like a started service. - if (app.hasShownUi && app != mHomeProcess) { - // If this process has shown some UI, let it immediately - // go to the LRU list because it may be pretty heavy with - // UI stuff. We'll tag it with a label just to help - // debug and understand what is going on. + app.hidden = false; + clientAdj = adj; + } else { + if (now >= (s.lastActivity + + ActiveServices.MAX_SERVICE_INACTIVITY)) { + // This service has not seen activity within + // recent memory, so allow it to drop to the + // LRU list if there is no other reason to keep + // it around. We'll also tag it with a label just + // to help debug and undertand what is going on. if (adj > clientAdj) { - adjType = "bound-bg-ui-services"; + adjType = "bound-bg-services"; } - app.hidden = false; clientAdj = adj; - } else { - if (now >= (s.lastActivity - + ActiveServices.MAX_SERVICE_INACTIVITY)) { - // This service has not seen activity within - // recent memory, so allow it to drop to the - // LRU list if there is no other reason to keep - // it around. We'll also tag it with a label just - // to help debug and undertand what is going on. - if (adj > clientAdj) { - adjType = "bound-bg-services"; - } - clientAdj = adj; - } - } - } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { - if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { - // If this connection is keeping the service - // created, then we want to try to better follow - // its memory management semantics for activities. - // That is, if it is sitting in the background - // LRU list as a hidden process (with activities), - // we don't want the service it is connected to - // to go into the empty LRU and quickly get killed, - // because I'll we'll do is just end up restarting - // the service. - app.hasClientActivities |= client.hasActivities; } } - if (adj > clientAdj) { - // If this process has recently shown UI, and - // the process that is binding to it is less - // important than being visible, then we don't - // care about the binding as much as we care - // about letting this process get into the LRU - // list to be killed and restarted if needed for - // memory. - if (app.hasShownUi && app != mHomeProcess - && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { - adjType = "bound-bg-ui-services"; + } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { + if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { + // If this connection is keeping the service + // created, then we want to try to better follow + // its memory management semantics for activities. + // That is, if it is sitting in the background + // LRU list as a hidden process (with activities), + // we don't want the service it is connected to + // to go into the empty LRU and quickly get killed, + // because I'll we'll do is just end up restarting + // the service. + app.hasClientActivities |= client.hasActivities; + } + } + if (adj > clientAdj) { + // If this process has recently shown UI, and + // the process that is binding to it is less + // important than being visible, then we don't + // care about the binding as much as we care + // about letting this process get into the LRU + // list to be killed and restarted if needed for + // memory. + if (app.hasShownUi && app != mHomeProcess + && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { + adjType = "bound-bg-ui-services"; + } else { + if ((cr.flags&(Context.BIND_ABOVE_CLIENT + |Context.BIND_IMPORTANT)) != 0) { + adj = clientAdj; + } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 + && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ + && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { + adj = ProcessList.PERCEPTIBLE_APP_ADJ; + } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { + adj = clientAdj; } else { - if ((cr.flags&(Context.BIND_ABOVE_CLIENT - |Context.BIND_IMPORTANT)) != 0) { - adj = clientAdj; - } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 - && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ - && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { - adj = ProcessList.PERCEPTIBLE_APP_ADJ; - } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { - adj = clientAdj; - } else { - app.pendingUiClean = true; - if (adj > ProcessList.VISIBLE_APP_ADJ) { - adj = ProcessList.VISIBLE_APP_ADJ; - } - } - if (!client.hidden) { - app.hidden = false; - } - if (client.keeping) { - app.keeping = true; + app.pendingUiClean = true; + if (adj > ProcessList.VISIBLE_APP_ADJ) { + adj = ProcessList.VISIBLE_APP_ADJ; } - adjType = "service"; } - } - if (adjType != null) { - app.adjType = adjType; - app.adjTypeCode = ActivityManager.RunningAppProcessInfo - .REASON_SERVICE_IN_USE; - app.adjSource = cr.binding.client; - app.adjSourceOom = clientAdj; - app.adjTarget = s.name; - } - if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { - if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { - schedGroup = Process.THREAD_GROUP_DEFAULT; + if (!client.hidden) { + app.hidden = false; + } + if (client.keeping) { + app.keeping = true; } + adjType = "service"; } } - final ActivityRecord a = cr.activity; - if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { - if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && - (a.visible || a.state == ActivityState.RESUMED - || a.state == ActivityState.PAUSING)) { - adj = ProcessList.FOREGROUND_APP_ADJ; - if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { - schedGroup = Process.THREAD_GROUP_DEFAULT; - } - app.hidden = false; - app.adjType = "service"; - app.adjTypeCode = ActivityManager.RunningAppProcessInfo - .REASON_SERVICE_IN_USE; - app.adjSource = a; - app.adjSourceOom = adj; - app.adjTarget = s.name; + if (adjType != null) { + app.adjType = adjType; + app.adjTypeCode = ActivityManager.RunningAppProcessInfo + .REASON_SERVICE_IN_USE; + app.adjSource = cr.binding.client; + app.adjSourceOom = clientAdj; + app.adjTarget = s.name; + } + if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { + if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { + schedGroup = Process.THREAD_GROUP_DEFAULT; + } + } + } + final ActivityRecord a = cr.activity; + if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { + if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && + (a.visible || a.state == ActivityState.RESUMED + || a.state == ActivityState.PAUSING)) { + adj = ProcessList.FOREGROUND_APP_ADJ; + if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { + schedGroup = Process.THREAD_GROUP_DEFAULT; } + app.hidden = false; + app.adjType = "service"; + app.adjTypeCode = ActivityManager.RunningAppProcessInfo + .REASON_SERVICE_IN_USE; + app.adjSource = a; + app.adjSourceOom = adj; + app.adjTarget = s.name; } } } @@ -13289,85 +13302,83 @@ public final class ActivityManagerService extends ActivityManagerNative } } - if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ - || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { - Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); - while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ - || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { - ContentProviderRecord cpr = jt.next(); - for (int i = cpr.connections.size()-1; - i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ - || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); - i--) { - ContentProviderConnection conn = cpr.connections.get(i); - ProcessRecord client = conn.client; - if (client == app) { - // Being our own client is not interesting. - continue; + for (int provi = app.pubProviders.size()-1; + provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ + || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); + provi--) { + ContentProviderRecord cpr = app.pubProviders.valueAt(provi); + for (int i = cpr.connections.size()-1; + i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ + || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); + i--) { + ContentProviderConnection conn = cpr.connections.get(i); + ProcessRecord client = conn.client; + if (client == app) { + // Being our own client is not interesting. + continue; + } + int myHiddenAdj = hiddenAdj; + if (myHiddenAdj > client.hiddenAdj) { + if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { + myHiddenAdj = client.hiddenAdj; + } else { + myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; } - int myHiddenAdj = hiddenAdj; - if (myHiddenAdj > client.hiddenAdj) { - if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { - myHiddenAdj = client.hiddenAdj; - } else { - myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; - } + } + int myClientHiddenAdj = clientHiddenAdj; + if (myClientHiddenAdj > client.clientHiddenAdj) { + if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { + myClientHiddenAdj = client.clientHiddenAdj; + } else { + myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; } - int myClientHiddenAdj = clientHiddenAdj; - if (myClientHiddenAdj > client.clientHiddenAdj) { - if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) { - myClientHiddenAdj = client.clientHiddenAdj; - } else { - myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; - } + } + int myEmptyAdj = emptyAdj; + if (myEmptyAdj > client.emptyAdj) { + if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { + myEmptyAdj = client.emptyAdj; + } else { + myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; } - int myEmptyAdj = emptyAdj; - if (myEmptyAdj > client.emptyAdj) { - if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { - myEmptyAdj = client.emptyAdj; - } else { - myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; - } + } + int clientAdj = computeOomAdjLocked(client, myHiddenAdj, + myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); + if (adj > clientAdj) { + if (app.hasShownUi && app != mHomeProcess + && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { + app.adjType = "bg-ui-provider"; + } else { + adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ + ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; + app.adjType = "provider"; } - int clientAdj = computeOomAdjLocked(client, myHiddenAdj, - myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll); - if (adj > clientAdj) { - if (app.hasShownUi && app != mHomeProcess - && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { - app.adjType = "bg-ui-provider"; - } else { - adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ - ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; - app.adjType = "provider"; - } - if (!client.hidden) { - app.hidden = false; - } - if (client.keeping) { - app.keeping = true; - } - app.adjTypeCode = ActivityManager.RunningAppProcessInfo - .REASON_PROVIDER_IN_USE; - app.adjSource = client; - app.adjSourceOom = clientAdj; - app.adjTarget = cpr.name; - } - if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { - schedGroup = Process.THREAD_GROUP_DEFAULT; - } - } - // If the provider has external (non-framework) process - // dependencies, ensure that its adjustment is at least - // FOREGROUND_APP_ADJ. - if (cpr.hasExternalProcessHandles()) { - if (adj > ProcessList.FOREGROUND_APP_ADJ) { - adj = ProcessList.FOREGROUND_APP_ADJ; - schedGroup = Process.THREAD_GROUP_DEFAULT; + if (!client.hidden) { app.hidden = false; + } + if (client.keeping) { app.keeping = true; - app.adjType = "provider"; - app.adjTarget = cpr.name; } + app.adjTypeCode = ActivityManager.RunningAppProcessInfo + .REASON_PROVIDER_IN_USE; + app.adjSource = client; + app.adjSourceOom = clientAdj; + app.adjTarget = cpr.name; + } + if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { + schedGroup = Process.THREAD_GROUP_DEFAULT; + } + } + // If the provider has external (non-framework) process + // dependencies, ensure that its adjustment is at least + // FOREGROUND_APP_ADJ. + if (cpr.hasExternalProcessHandles()) { + if (adj > ProcessList.FOREGROUND_APP_ADJ) { + adj = ProcessList.FOREGROUND_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; + app.hidden = false; + app.keeping = true; + app.adjType = "provider"; + app.adjTarget = cpr.name; } } } diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index d6a6eb8..f97b720 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -3333,14 +3333,16 @@ final class ActivityStack { } } - void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, - boolean dumpClient, String dumpPackage) { + boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, + boolean dumpClient, String dumpPackage, boolean needSep) { + boolean printed = false; for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); - pw.print(" Task "); pw.print(taskNdx); pw.print(": id #"); pw.println(task.taskId); - ActivityStackSupervisor.dumpHistoryList(fd, pw, mTaskHistory.get(taskNdx).mActivities, - " ", "Hist", true, !dumpAll, dumpClient, dumpPackage); + printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw, + mTaskHistory.get(taskNdx).mActivities, " ", "Hist", true, !dumpAll, + dumpClient, dumpPackage, needSep, " Task " + taskNdx + ": id #" + task.taskId); } + return printed; } ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index bddca2b..a638981 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -2215,82 +2215,95 @@ public class ActivityStackSupervisor { return getFocusedStack().getDumpActivitiesLocked(name); } + static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, + boolean needSep, String prefix) { + if (activity != null) { + if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { + if (needSep) { + pw.println(); + needSep = false; + } + pw.print(prefix); + pw.println(activity); + } + } + return needSep; + } + boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, String dumpPackage) { - pw.print(" mStackState="); pw.println(stackStateToString(mStackState)); - if (mGoingToSleepActivities.size() > 0) { - pw.println(" Activities waiting to sleep:"); - dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, false, - dumpPackage); - } - if (dumpAll) { - pw.println(" mSleepTimeout: " + mSleepTimeout); - } final int numStacks = mStacks.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); - pw.print(" Stack #"); pw.print(mStacks.indexOf(stack)); pw.println(":"); - stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage); - pw.println(" "); - pw.println(" Running activities (most recent first):"); - dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false, - dumpPackage); - - pw.print(" Stack #"); pw.println(mStacks.indexOf(stack)); - if (stack.mPausingActivity != null) { - pw.println(" mPausingActivity: " + stack.mPausingActivity); + if (stackNdx != 0) { + pw.println(); } - pw.println(" mResumedActivity: " + stack.mResumedActivity); + pw.print(" Stack #"); pw.print(mStacks.indexOf(stack)); pw.println(":"); + stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, false); + dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false, + dumpPackage, true, " Running activities (most recent first):"); + + boolean needSep = true; + needSep = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, + " mPausingActivity: "); + needSep = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, + " mResumedActivity: "); if (dumpAll) { - pw.println(" mLastPausedActivity: " + stack.mLastPausedActivity); + printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, + " mLastPausedActivity: "); } } - if (mFinishingActivities.size() > 0) { - pw.println(" "); - pw.println(" Activities waiting to finish:"); - dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, false, - dumpPackage); - } - - if (mStoppingActivities.size() > 0) { - pw.println(" "); - pw.println(" Activities waiting to stop:"); - dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, false, - dumpPackage); - } + dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, false, + dumpPackage, true, " Activities waiting to finish:"); + dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, false, + dumpPackage, true, " Activities waiting to stop:"); + dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, + false, dumpPackage, true, " Activities waiting for another to become visible:"); + dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, false, + dumpPackage, true, " Activities waiting to sleep:"); + dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, false, + dumpPackage, true, " Activities waiting to sleep:"); - if (mWaitingVisibleActivities.size() > 0) { - pw.println(" "); - pw.println(" Activities waiting for another to become visible:"); - dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, - false, dumpPackage); - } - - if (dumpAll) { - pw.println(" "); - pw.println(" mCurTaskId: " + mCurTaskId); + if (dumpPackage == null) { + pw.println(); + pw.print(" mStackState="); pw.println(stackStateToString(mStackState)); + if (dumpAll) { + pw.println(" mSleepTimeout: " + mSleepTimeout); + } + if (dumpAll) { + pw.println(" mCurTaskId: " + mCurTaskId); + } } return true; } - static void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, + static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, String prefix, String label, boolean complete, boolean brief, boolean client, - String dumpPackage) { + String dumpPackage, boolean needNL, String header) { TaskRecord lastTask = null; - boolean needNL = false; - final String innerPrefix = prefix + " "; - final String[] args = new String[0]; + String innerPrefix = null; + String[] args = null; + boolean printed = false; for (int i=list.size()-1; i>=0; i--) { final ActivityRecord r = list.get(i); if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { continue; } + if (innerPrefix == null) { + innerPrefix = prefix + " "; + args = new String[0]; + } + printed = true; final boolean full = !brief && (complete || !r.isInHistory()); if (needNL) { - pw.println(" "); + pw.println(""); needNL = false; } + if (header != null) { + pw.println(header); + header = null; + } if (lastTask != r.task) { lastTask = r.task; pw.print(prefix); @@ -2341,6 +2354,7 @@ public class ActivityStackSupervisor { needNL = true; } } + return printed; } void scheduleIdleTimeoutLocked(ActivityRecord next) { diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index 7929f96..3a4a34c 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -32,12 +32,12 @@ import android.os.IBinder; import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; +import android.util.ArrayMap; import android.util.PrintWriterPrinter; import android.util.TimeUtils; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; /** @@ -129,8 +129,8 @@ class ProcessRecord { // all IIntentReceivers that are registered from this process. final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>(); // class (String) -> ContentProviderRecord - final HashMap<String, ContentProviderRecord> pubProviders - = new HashMap<String, ContentProviderRecord>(); + final ArrayMap<String, ContentProviderRecord> pubProviders + = new ArrayMap<String, ContentProviderRecord>(); // All ContentProviderRecord process is using final ArrayList<ContentProviderConnection> conProviders = new ArrayList<ContentProviderConnection>(); @@ -302,9 +302,9 @@ class ProcessRecord { } if (pubProviders.size() > 0) { pw.print(prefix); pw.println("Published Providers:"); - for (HashMap.Entry<String, ContentProviderRecord> ent : pubProviders.entrySet()) { - pw.print(prefix); pw.print(" - "); pw.println(ent.getKey()); - pw.print(prefix); pw.print(" -> "); pw.println(ent.getValue()); + for (int i=0; i<pubProviders.size(); i++) { + pw.print(prefix); pw.print(" - "); pw.println(pubProviders.keyAt(i)); + pw.print(prefix); pw.print(" -> "); pw.println(pubProviders.valueAt(i)); } } if (conProviders.size() > 0) { diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java index 9dbf5f5..3249e1e 100644 --- a/services/java/com/android/server/am/ProviderMap.java +++ b/services/java/com/android/server/am/ProviderMap.java @@ -230,58 +230,88 @@ public class ProviderMap { return didSomething; } - private void dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll, - HashMap<ComponentName, ContentProviderRecord> map) { + private boolean dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll, String dumpPackage, + String header, boolean needSep, HashMap<ComponentName, ContentProviderRecord> map) { Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it = map.entrySet().iterator(); + boolean written = false; while (it.hasNext()) { Map.Entry<ComponentName, ContentProviderRecord> e = it.next(); ContentProviderRecord r = e.getValue(); + if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { + continue; + } + if (needSep) { + pw.println(""); + needSep = false; + } + if (header != null) { + pw.println(header); + header = null; + } + written = true; pw.print(" * "); pw.println(r); r.dump(pw, " ", dumpAll); } + return written; } - private void dumpProvidersByNameLocked(PrintWriter pw, - HashMap<String, ContentProviderRecord> map) { + private boolean dumpProvidersByNameLocked(PrintWriter pw, String dumpPackage, + String header, boolean needSep, HashMap<String, ContentProviderRecord> map) { Iterator<Map.Entry<String, ContentProviderRecord>> it = map.entrySet().iterator(); + boolean written = false; while (it.hasNext()) { Map.Entry<String, ContentProviderRecord> e = it.next(); ContentProviderRecord r = e.getValue(); + if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { + continue; + } + if (needSep) { + pw.println(""); + needSep = false; + } + if (header != null) { + pw.println(header); + header = null; + } + written = true; pw.print(" "); pw.print(e.getKey()); pw.print(": "); pw.println(r.toShortString()); } + return written; } - void dumpProvidersLocked(PrintWriter pw, boolean dumpAll) { + boolean dumpProvidersLocked(PrintWriter pw, boolean dumpAll, String dumpPackage) { + boolean needSep = false; + if (mSingletonByClass.size() > 0) { pw.println(" Published single-user content providers (by class):"); - dumpProvidersByClassLocked(pw, dumpAll, mSingletonByClass); + needSep = dumpProvidersByClassLocked(pw, dumpAll, dumpPackage, + " Published single-user content providers (by class):", needSep, + mSingletonByClass); } - pw.println(""); for (int i = 0; i < mProvidersByClassPerUser.size(); i++) { HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i); - pw.println(""); - pw.println(" Published user " + mProvidersByClassPerUser.keyAt(i) - + " content providers (by class):"); - dumpProvidersByClassLocked(pw, dumpAll, map); + needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage, + " Published user " + mProvidersByClassPerUser.keyAt(i) + + " content providers (by class):", needSep, map); } if (dumpAll) { - pw.println(""); - pw.println(" Single-user authority to provider mappings:"); - dumpProvidersByNameLocked(pw, mSingletonByName); + needSep |= dumpProvidersByNameLocked(pw, dumpPackage, + " Single-user authority to provider mappings:", needSep, mSingletonByName); for (int i = 0; i < mProvidersByNamePerUser.size(); i++) { - pw.println(""); - pw.println(" User " + mProvidersByNamePerUser.keyAt(i) - + " authority to provider mappings:"); - dumpProvidersByNameLocked(pw, mProvidersByNamePerUser.valueAt(i)); + needSep |= dumpProvidersByNameLocked(pw, dumpPackage, + " User " + mProvidersByNamePerUser.keyAt(i) + + " authority to provider mappings:", needSep, + mProvidersByNamePerUser.valueAt(i)); } } + return needSep; } protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java index 9fdd293..707e8ee 100644 --- a/services/java/com/android/server/am/ServiceRecord.java +++ b/services/java/com/android/server/am/ServiceRecord.java @@ -16,34 +16,32 @@ package com.android.server.am; -import android.app.PendingIntent; -import android.net.Uri; -import android.provider.Settings; import com.android.internal.os.BatteryStatsImpl; import com.android.server.NotificationManagerService; import android.app.INotificationManager; import android.app.Notification; import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; +import android.net.Uri; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; +import android.provider.Settings; +import android.util.ArrayMap; import android.util.Slog; import android.util.TimeUtils; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; /** @@ -76,11 +74,11 @@ class ServiceRecord extends Binder { final boolean exported; // from ServiceInfo.exported final Runnable restarter; // used to schedule retries of starting the service final long createTime; // when this service was created - final HashMap<Intent.FilterComparison, IntentBindRecord> bindings - = new HashMap<Intent.FilterComparison, IntentBindRecord>(); + final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings + = new ArrayMap<Intent.FilterComparison, IntentBindRecord>(); // All active bindings to the service. - final HashMap<IBinder, ArrayList<ConnectionRecord>> connections - = new HashMap<IBinder, ArrayList<ConnectionRecord>>(); + final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections + = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>(); // IBinder -> ConnectionRecord of all bound clients ProcessRecord app; // where this service is running or null. @@ -258,10 +256,9 @@ class ServiceRecord extends Binder { dumpStartList(pw, prefix, pendingStarts, 0); } if (bindings.size() > 0) { - Iterator<IntentBindRecord> it = bindings.values().iterator(); pw.print(prefix); pw.println("Bindings:"); - while (it.hasNext()) { - IntentBindRecord b = it.next(); + for (int i=0; i<bindings.size(); i++) { + IntentBindRecord b = bindings.valueAt(i); pw.print(prefix); pw.print("* IntentBindRecord{"); pw.print(Integer.toHexString(System.identityHashCode(b))); if ((b.collectFlags()&Context.BIND_AUTO_CREATE) != 0) { @@ -273,9 +270,8 @@ class ServiceRecord extends Binder { } if (connections.size() > 0) { pw.print(prefix); pw.println("All Connections:"); - Iterator<ArrayList<ConnectionRecord>> it = connections.values().iterator(); - while (it.hasNext()) { - ArrayList<ConnectionRecord> c = it.next(); + for (int conni=0; conni<connections.size(); conni++) { + ArrayList<ConnectionRecord> c = connections.valueAt(conni); for (int i=0; i<c.size(); i++) { pw.print(prefix); pw.print(" "); pw.println(c.get(i)); } |