Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b2681ba authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android Git Automerger
Browse files

am 3af8b88d: Merge "Add drop box reports of low memory." into ics-mr1

* commit '3af8b88d':
  Add drop box reports of low memory.
parents 3a77503c 3af8b88d
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -109,6 +109,10 @@ public class Am {
            runStartService();
        } else if (op.equals("force-stop")) {
            runForceStop();
        } else if (op.equals("kill")) {
            runKill();
        } else if (op.equals("kill-all")) {
            runKillAll();
        } else if (op.equals("instrument")) {
            runInstrument();
        } else if (op.equals("broadcast")) {
@@ -484,6 +488,14 @@ public class Am {
        mAm.forceStopPackage(nextArgRequired());
    }

    private void runKill() throws Exception {
        mAm.killBackgroundProcesses(nextArgRequired());
    }

    private void runKillAll() throws Exception {
        mAm.killAllBackgroundProcesses();
    }

    private void sendBroadcast() throws Exception {
        Intent intent = makeIntent();
        IntentReceiver receiver = new IntentReceiver();
@@ -1179,6 +1191,8 @@ public class Am {
                "               [--R COUNT] [-S] <INTENT>\n" +
                "       am startservice <INTENT>\n" +
                "       am force-stop <PACKAGE>\n" +
                "       am kill <PACKAGE>\n" +
                "       am kill-all\n" +
                "       am broadcast <INTENT>\n" +
                "       am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
                "               [--no-window-animation] <COMPONENT>\n" +
@@ -1202,6 +1216,12 @@ public class Am {
                "\n" +
                "am force-stop: force stop everything associated with <PACKAGE>.\n" +
                "\n" +
                "am kill: Kill all processes associated with <PACKAGE>.  Only kills.\n" +
                "  processes that are safe to kill -- that is, will not impact the user\n" +
                "  experience.\n" +
                "\n" +
                "am kill-all: Kill all background processes.\n" +
                "\n" +
                "am broadcast: send a broadcast Intent.\n" +
                "\n" +
                "am instrument: start an Instrumentation.  Typically this target <COMPONENT>\n" +
+19 −2
Original line number Diff line number Diff line
@@ -1093,6 +1093,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            return true;
        }

        case KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            killAllBackgroundProcesses();
            reply.writeNoException();
            return true;
        }
        
        case FORCE_STOP_PACKAGE_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            String packageName = data.readString();
@@ -2918,6 +2925,16 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }

    public void killAllBackgroundProcesses() throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        mRemote.transact(KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

    public void forceStopPackage(String packageName) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
+2 −0
Original line number Diff line number Diff line
@@ -234,6 +234,7 @@ public interface IActivityManager extends IInterface {
    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) throws RemoteException;
    
    public void killBackgroundProcesses(final String packageName) throws RemoteException;
    public void killAllBackgroundProcesses() throws RemoteException;
    public void forceStopPackage(final String packageName) throws RemoteException;
    
    // Note: probably don't want to allow applications access to these.
@@ -605,4 +606,5 @@ public interface IActivityManager extends IInterface {
    int GET_PROCESS_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+136;
    int SHOW_BOOT_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+137;
    int DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+138;
    int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139;
}
+84 −20
Original line number Diff line number Diff line
@@ -1220,6 +1220,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
                Thread thread = new Thread() {
                    @Override public void run() {
                        StringBuilder dropBuilder = new StringBuilder(1024);
                        StringBuilder logBuilder = new StringBuilder(1024);
                        try {
                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
                                    "procrank", });
@@ -1233,16 +1235,29 @@ public final class ActivityManagerService extends ActivityManagerNative
                                    break;
                                }
                                if (line.length() > 0) {
                                    Slog.i(TAG, line);
                                    logBuilder.append(line);
                                    logBuilder.append('\n');
                                }
                                dropBuilder.append(line);
                                dropBuilder.append('\n');
                            }
                            converter.close();
                        } catch (IOException e) {
                        }
                        StringWriter sw = new StringWriter();
                        PrintWriter pw = new PrintWriter(sw);
                        dumpApplicationMemoryUsage(null, pw, "  ", new String[] { }, true);
                        Slog.i(TAG, sw.toString());
                        StringWriter catSw = new StringWriter();
                        PrintWriter catPw = new PrintWriter(catSw);
                        dumpApplicationMemoryUsage(null, pw, "  ", new String[] { }, true, catPw);
                        String memUsage = sw.toString();
                        dropBuilder.append('\n');
                        dropBuilder.append(memUsage);
                        dropBuilder.append(catSw.toString());
                        logBuilder.append(memUsage);
                        addErrorToDropBox("watchdog", null, "system_server", null,
                                null, "Low on memory -- no more background processes",
                                dropBuilder.toString(), null, null);
                        Slog.i(TAG, logBuilder.toString());
                        synchronized (ActivityManagerService.this) {
                            long now = SystemClock.uptimeMillis();
                            if (mLastMemUsageReportTime < now) {
@@ -1394,7 +1409,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                return;
            }
            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false);
            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
        }
    }
@@ -3192,7 +3207,49 @@ public final class ActivityManagerService extends ActivityManagerNative
                    return;
                }
                killPackageProcessesLocked(packageName, pkgUid,
                        ProcessList.SERVICE_ADJ, false, true, true, false);
                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }
    public void killAllBackgroundProcesses() {
        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
                != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid()
                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
        
        long callingId = Binder.clearCallingIdentity();
        try {
            synchronized(this) {
                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
                    final int NA = apps.size();
                    for (int ia=0; ia<NA; ia++) {
                        ProcessRecord app = apps.valueAt(ia);
                        if (app.persistent) {
                            // we don't kill persistent processes
                            continue;
                        }
                        if (app.removed) {
                            procs.add(app);
                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
                            app.removed = true;
                            procs.add(app);
                        }
                    }
                }
                
                int N = procs.size();
                for (int i=0; i<N; i++) {
                    removeProcessLocked(procs.get(i), false, true, "kill all background");
                }
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
@@ -3364,7 +3421,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    
    private final boolean killPackageProcessesLocked(String packageName, int uid,
            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
            boolean evenPersistent) {
            boolean evenPersistent, String reason) {
        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
        // Remove all processes this package may have touched: all with the
@@ -3399,7 +3456,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        
        int N = procs.size();
        for (int i=0; i<N; i++) {
            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
        }
        return N > 0;
    }
@@ -3430,7 +3487,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
        
        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
                callerWillRestart, false, doit, evenPersistent);
                callerWillRestart, false, doit, evenPersistent, "force stop");
        
        TaskRecord lastTask = null;
        for (i=0; i<mMainStack.mHistory.size(); i++) {
@@ -3518,11 +3575,11 @@ public final class ActivityManagerService extends ActivityManagerNative
    }
    private final boolean removeProcessLocked(ProcessRecord app,
            boolean callerWillRestart, boolean allowRestart) {
            boolean callerWillRestart, boolean allowRestart, String reason) {
        final String name = app.processName;
        final int uid = app.info.uid;
        if (DEBUG_PROCESSES) Slog.d(
            TAG, "Force removing process " + app + " (" + name
            TAG, "Force removing proc " + app.toShortString() + " (" + name
            + "/" + uid + ")");
        mProcessNames.remove(name, uid);
@@ -3537,9 +3594,10 @@ public final class ActivityManagerService extends ActivityManagerNative
                mPidsSelfLocked.remove(pid);
                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            }
            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
            handleAppDiedLocked(app, true, allowRestart);
            mLruProcesses.remove(app);
            Process.killProcess(pid);
            Process.killProcessQuiet(pid);
            
            if (app.persistent) {
                if (!callerWillRestart) {
@@ -6846,7 +6904,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                for (int i=procsToKill.size()-1; i>=0; i--) {
                    ProcessRecord proc = procsToKill.get(i);
                    Slog.i(TAG, "Removing system update proc: " + proc);
                    removeProcessLocked(proc, true, false);
                    removeProcessLocked(proc, true, false, "system update done");
                }
            }
            
@@ -7042,7 +7100,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                // Don't let services in this process be restarted and potentially
                // annoy the user repeatedly.  Unless it is persistent, since those
                // processes run critical code.
                removeProcessLocked(app, false, false);
                removeProcessLocked(app, false, false, "crash");
                mMainStack.resumeTopActivityLocked(null);
                return false;
            }
@@ -9298,8 +9356,10 @@ public final class ActivityManagerService extends ActivityManagerNative
    }
    final void dumpApplicationMemoryUsage(FileDescriptor fd,
            PrintWriter pw, String prefix, String[] args, boolean brief) {
            PrintWriter pw, String prefix, String[] args, boolean brief,
            PrintWriter categoryPw) {
        boolean dumpAll = false;
        boolean oomOnly = false;
        
        int opti = 0;
        while (opti < args.length) {
@@ -9310,9 +9370,12 @@ public final class ActivityManagerService extends ActivityManagerNative
            opti++;
            if ("-a".equals(opt)) {
                dumpAll = true;
            } else if ("--oom".equals(opt)) {
                oomOnly = true;
            } else if ("-h".equals(opt)) {
                pw.println("meminfo dump options: [-a] [process]");
                pw.println("meminfo dump options: [-a] [--oom] [process]");
                pw.println("  -a: include all available information for each process.");
                pw.println("  --oom: only show processes organized by oom adj.");
                pw.println("If [process] is specified it can be the name or ");
                pw.println("pid of a specific process to dump.");
                return;
@@ -9438,7 +9501,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
            }
            if (!brief) {
            if (!brief && !oomOnly) {
                pw.println();
                pw.println("Total PSS by process:");
                dumpMemItems(pw, "  ", procMems, true);
@@ -9446,10 +9509,11 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
            pw.println("Total PSS by OOM adjustment:");
            dumpMemItems(pw, "  ", oomMems, false);
            if (!brief) {
                pw.println();
                pw.println("Total PSS by category:");
                dumpMemItems(pw, "  ", catMems, true);
            if (!oomOnly) {
                PrintWriter out = categoryPw != null ? categoryPw : pw;
                out.println();
                out.println("Total PSS by category:");
                dumpMemItems(out, "  ", catMems, true);
            }
            pw.println();
            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");