From 237cefbcee8721e3268ba778297a0ad48e67f079 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 22 Oct 2013 18:45:27 -0700 Subject: [PATCH] Fix issue #11323037: Android apk incorrectly marked as running in app processes The android package is now a special case, not being added to the package list when creating a multi-process component. There is no need, since this package is actually the framework itself which must be loaded in every process. Also cleaned up some of the procstats dump output to help see what is going on here. Change-Id: If65d35ecd562f3154bdebfded69c454af6ce8c96 --- .../android/internal/app/ProcessStats.java | 70 +++++++++++-------- .../server/am/ActivityManagerService.java | 11 ++- .../server/am/ActivityStackSupervisor.java | 9 ++- .../server/am/ProcessStatsService.java | 64 +++++++++++------ 4 files changed, 99 insertions(+), 55 deletions(-) diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java index 222e44673c413..20b8c95164cdb 100644 --- a/core/java/com/android/internal/app/ProcessStats.java +++ b/core/java/com/android/internal/app/ProcessStats.java @@ -135,10 +135,10 @@ public final class ProcessStats implements Parcelable { }; static final String[] STATE_NAMES = new String[] { - "Persistent", "Top ", "Imp Fg ", "Imp Bg ", - "Backup ", "Heavy Wght", "Service ", "Service Rs", - "Receiver ", "Home ", - "Last Act ", "Cch Act ", "Cch CliAct", "Cch Empty " + "Persist", "Top ", "ImpFg ", "ImpBg ", + "Backup ", "HeavyWt", "Service", "ServRst", + "Receivr", "Home ", + "LastAct", "CchAct ", "CchCAct", "CchEmty" }; public static final String[] ADJ_SCREEN_NAMES_CSV = new String[] { @@ -314,16 +314,16 @@ public final class ProcessStats implements Parcelable { private static void printScreenLabel(PrintWriter pw, int offset) { switch (offset) { case ADJ_NOTHING: - pw.print(" "); + pw.print(" "); break; case ADJ_SCREEN_OFF: - pw.print("Screen Off / "); + pw.print("SOff/"); break; case ADJ_SCREEN_ON: - pw.print("Screen On / "); + pw.print("SOn /"); break; default: - pw.print("?????????? / "); + pw.print("????/"); break; } } @@ -344,25 +344,31 @@ public final class ProcessStats implements Parcelable { } } - private static void printMemLabel(PrintWriter pw, int offset) { + private static void printMemLabel(PrintWriter pw, int offset, char sep) { switch (offset) { case ADJ_NOTHING: - pw.print(" "); + pw.print(" "); + if (sep != 0) pw.print(' '); break; case ADJ_MEM_FACTOR_NORMAL: - pw.print("Norm / "); + pw.print("Norm"); + if (sep != 0) pw.print(sep); break; case ADJ_MEM_FACTOR_MODERATE: - pw.print("Mod / "); + pw.print("Mod "); + if (sep != 0) pw.print(sep); break; case ADJ_MEM_FACTOR_LOW: - pw.print("Low / "); + pw.print("Low "); + if (sep != 0) pw.print(sep); break; case ADJ_MEM_FACTOR_CRITICAL: - pw.print("Crit / "); + pw.print("Crit"); + if (sep != 0) pw.print(sep); break; default: - pw.print("???? / "); + pw.print("????"); + if (sep != 0) pw.print(sep); break; } } @@ -399,8 +405,9 @@ public final class ProcessStats implements Parcelable { printScreenLabel(pw, printedScreen != iscreen ? iscreen : STATE_NOTHING); printedScreen = iscreen; - printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING); + printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, (char)0); printedMem = imem; + pw.print(": "); TimeUtils.formatDuration(time, pw); pw.println(running); } totalTime += time; @@ -409,8 +416,7 @@ public final class ProcessStats implements Parcelable { } if (totalTime != 0 && pw != null) { pw.print(prefix); - printScreenLabel(pw, STATE_NOTHING); - pw.print("TOTAL: "); + pw.print(" TOTAL: "); TimeUtils.formatDuration(totalTime, pw); pw.println(); } @@ -569,7 +575,7 @@ public final class ProcessStats implements Parcelable { printedScreen = iscreen; } if (memStates.length > 1) { - printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING); + printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, '/'); printedMem = imem; } pw.print(STATE_NAMES[procStates[ip]]); pw.print(": "); @@ -585,9 +591,9 @@ public final class ProcessStats implements Parcelable { printScreenLabel(pw, STATE_NOTHING); } if (memStates.length > 1) { - printMemLabel(pw, STATE_NOTHING); + printMemLabel(pw, STATE_NOTHING, '/'); } - pw.print("TOTAL : "); + pw.print("TOTAL : "); TimeUtils.formatDuration(totalTime, pw); pw.println(); } @@ -621,7 +627,7 @@ public final class ProcessStats implements Parcelable { printedScreen = iscreen; } if (memStates.length > 1) { - printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING); + printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, '/'); printedMem = imem; } pw.print(STATE_NAMES[procStates[ip]]); pw.print(": "); @@ -798,7 +804,7 @@ public final class ProcessStats implements Parcelable { new int[] {STATE_SERVICE_RESTARTING}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " Receiver: ", screenStates, memStates, new int[] {STATE_RECEIVER}, now, totalTime, true); - dumpProcessSummaryDetails(pw, proc, prefix, " Home: ", screenStates, memStates, + dumpProcessSummaryDetails(pw, proc, prefix, " (Home): ", screenStates, memStates, new int[] {STATE_HOME}, now, totalTime, true); dumpProcessSummaryDetails(pw, proc, prefix, " (Last Act): ", screenStates, memStates, new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true); @@ -1733,13 +1739,17 @@ public final class ProcessStats implements Parcelable { pw.print(" pkg="); pw.println(proc.mCommonProcess.mPackage); } } - pw.print(prefix); pw.print("mActive="); pw.println(proc.mActive); + if (proc.mActive) { + pw.print(prefix); pw.print("mActive="); pw.println(proc.mActive); + } if (proc.mDead) { pw.print(prefix); pw.print("mDead="); pw.println(proc.mDead); } - pw.print(prefix); pw.print("mNumActiveServices="); pw.print(proc.mNumActiveServices); - pw.print(" mNumStartedServices="); - pw.println(proc.mNumStartedServices); + if (proc.mNumActiveServices != 0 || proc.mNumStartedServices != 0) { + pw.print(prefix); pw.print("mNumActiveServices="); pw.print(proc.mNumActiveServices); + pw.print(" mNumStartedServices="); + pw.println(proc.mNumStartedServices); + } } public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary, @@ -1920,8 +1930,9 @@ public final class ProcessStats implements Parcelable { printScreenLabel(pw, printedScreen != iscreen ? iscreen : STATE_NOTHING); printedScreen = iscreen; - printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING); + printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, (char)0); printedMem = imem; + pw.print(": "); TimeUtils.formatDuration(time, pw); pw.println(running); } totalTime += time; @@ -1930,8 +1941,7 @@ public final class ProcessStats implements Parcelable { } if (totalTime != 0 && pw != null) { pw.print(prefix); - printScreenLabel(pw, STATE_NOTHING); - pw.print("TOTAL: "); + pw.print(" TOTAL: "); TimeUtils.formatDuration(totalTime, pw); pw.println(); } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 3ba90981eeed7..8b7fd8e917e20 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -7224,7 +7224,13 @@ public final class ActivityManagerService extends ActivityManagerNative if (DEBUG_MU) Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); app.pubProviders.put(cpi.name, cpr); - app.addPackage(cpi.applicationInfo.packageName, mProcessStats); + if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { + // Don't add this if it is a platform component that is marked + // to run in multiple processes, because this is actually + // part of the framework so doesn't make sense to track as a + // separate apk in the process. + app.addPackage(cpi.applicationInfo.packageName, mProcessStats); + } ensurePackageDexOpt(cpi.applicationInfo.packageName); } } @@ -12777,7 +12783,8 @@ public final class ActivityManagerService extends ActivityManagerNative + ") when registering receiver " + receiver); } if (callerApp.info.uid != Process.SYSTEM_UID && - !callerApp.pkgList.containsKey(callerPackage)) { + !callerApp.pkgList.containsKey(callerPackage) && + !"android".equals(callerPackage)) { throw new SecurityException("Given caller package " + callerPackage + " is not running in process " + callerApp); } diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index 523015da0f29b..b68b98bd5895a 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -1051,7 +1051,14 @@ public final class ActivityStackSupervisor { if (app != null && app.thread != null) { try { - app.addPackage(r.info.packageName, mService.mProcessStats); + if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 + || !"android".equals(r.info.packageName)) { + // Don't add this if it is a platform component that is marked + // to run in multiple processes, because this is actually + // part of the framework so doesn't make sense to track as a + // separate apk in the process. + app.addPackage(r.info.packageName, mService.mProcessStats); + } realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java index 50a7b5c5e56cd..8d168807bbd8d 100644 --- a/services/java/com/android/server/am/ProcessStatsService.java +++ b/services/java/com/android/server/am/ProcessStatsService.java @@ -529,6 +529,33 @@ public final class ProcessStatsService extends IProcessStats.Stub { } } + private void dumpAggregatedStats(PrintWriter pw, long aggregateHours, long now, + String reqPackage, boolean isCompact, boolean dumpDetails, boolean dumpFullDetails, + boolean dumpAll, boolean activeOnly) { + ParcelFileDescriptor pfd = getStatsOverTime(aggregateHours*60*60*1000 + - (ProcessStats.COMMIT_PERIOD/2)); + if (pfd == null) { + pw.println("Unable to build stats!"); + return; + } + ProcessStats stats = new ProcessStats(false); + InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(pfd); + stats.read(stream); + if (stats.mReadError != null) { + pw.print("Failure reading: "); pw.println(stats.mReadError); + return; + } + if (isCompact) { + stats.dumpCheckinLocked(pw, reqPackage); + } else { + if (dumpDetails || dumpFullDetails) { + stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly); + } else { + stats.dumpSummaryLocked(pw, reqPackage, now, activeOnly); + } + } + } + static private void dumpHelp(PrintWriter pw) { pw.println("Process stats (procstats) dump options:"); pw.println(" [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]"); @@ -789,28 +816,8 @@ public final class ProcessStatsService extends IProcessStats.Stub { } return; } else if (aggregateHours != 0) { - ParcelFileDescriptor pfd = getStatsOverTime(aggregateHours*60*60*1000 - - (ProcessStats.COMMIT_PERIOD/2)); - if (pfd == null) { - pw.println("Unable to build stats!"); - return; - } - ProcessStats stats = new ProcessStats(false); - InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(pfd); - stats.read(stream); - if (stats.mReadError != null) { - pw.print("Failure reading: "); pw.println(stats.mReadError); - return; - } - if (isCompact) { - stats.dumpCheckinLocked(pw, reqPackage); - } else { - if (dumpDetails || dumpFullDetails) { - stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly); - } else { - stats.dumpSummaryLocked(pw, reqPackage, now, activeOnly); - } - } + dumpAggregatedStats(pw, aggregateHours, now, reqPackage, isCompact, + dumpDetails, dumpFullDetails, dumpAll, activeOnly); return; } @@ -875,6 +882,19 @@ public final class ProcessStatsService extends IProcessStats.Stub { } } if (!isCheckin) { + if (dumpAll) { + if (sepNeeded) { + pw.println(); + pw.println("AGGREGATED OVER LAST 24 HOURS:"); + } + dumpAggregatedStats(pw, 24, now, reqPackage, isCompact, + dumpDetails, dumpFullDetails, dumpAll, activeOnly); + pw.println(); + pw.println("AGGREGATED OVER LAST 3 HOURS:"); + dumpAggregatedStats(pw, 3, now, reqPackage, isCompact, + dumpDetails, dumpFullDetails, dumpAll, activeOnly); + sepNeeded = true; + } synchronized (mAm) { if (isCompact) { mProcessStats.dumpCheckinLocked(pw, reqPackage);