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

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

am 03be79b3: am fbf4888d: am 9882d388: Merge "Fix issue #11223338: Not...

am 03be79b3: am fbf4888d: am 9882d388: Merge "Fix issue #11223338: Not retaining service started state while restarting" into klp-dev

* commit '03be79b3':
  Fix issue #11223338: Not retaining service started state while restarting
parents 7c482b4f 03be79b3
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -2272,9 +2272,12 @@ public class ActivityManager {
    public static void dumpPackageStateStatic(FileDescriptor fd, String packageName) {
        FileOutputStream fout = new FileOutputStream(fd);
        PrintWriter pw = new FastPrintWriter(fout);
        dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] { "package", packageName });
        dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] {
                "-a", "package", packageName });
        pw.println();
        dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { packageName });
        dumpService(pw, fd, "meminfo", new String[] { "--local", packageName });
        pw.println();
        dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { "-a", packageName });
        pw.println();
        dumpService(pw, fd, "usagestats", new String[] { "--packages", packageName });
        pw.println();
@@ -2296,7 +2299,7 @@ public class ActivityManager {
            pw.flush();
            tp = new TransferPipe();
            tp.setBufferPrefix("  ");
            service.dump(tp.getWriteFd().getFileDescriptor(), args);
            service.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
            tp.go(fd);
        } catch (Throwable e) {
            if (tp != null) {
+141 −80
Original line number Diff line number Diff line
@@ -1758,21 +1758,34 @@ public final class ProcessStats implements Parcelable {
                mStartTime, now);
        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
        boolean printedHeader = false;
        boolean sepNeeded = false;
        for (int ip=0; ip<pkgMap.size(); ip++) {
            String pkgName = pkgMap.keyAt(ip);
            if (reqPackage != null && !reqPackage.equals(pkgName)) {
                continue;
            }
            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
            final String pkgName = pkgMap.keyAt(ip);
            final SparseArray<PackageState> uids = pkgMap.valueAt(ip);
            for (int iu=0; iu<uids.size(); iu++) {
                int uid = uids.keyAt(iu);
                PackageState pkgState = uids.valueAt(iu);
                final int uid = uids.keyAt(iu);
                final PackageState pkgState = uids.valueAt(iu);
                final int NPROCS = pkgState.mProcesses.size();
                final int NSRVS = pkgState.mServices.size();
                final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
                if (!pkgMatch) {
                    boolean procMatch = false;
                    for (int iproc=0; iproc<NPROCS; iproc++) {
                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                        if (reqPackage.equals(proc.mName)) {
                            procMatch = true;
                            break;
                        }
                    }
                    if (!procMatch) {
                        continue;
                    }
                }
                if (NPROCS > 0 || NSRVS > 0) {
                    if (!printedHeader) {
                        pw.println("Per-Package Stats:");
                        printedHeader = true;
                        sepNeeded = true;
                    }
                    pw.print("  * "); pw.print(pkgName); pw.print(" / ");
                            UserHandle.formatUid(pw, uid); pw.println(":");
@@ -1780,6 +1793,9 @@ public final class ProcessStats implements Parcelable {
                if (!dumpSummary || dumpAll) {
                    for (int iproc=0; iproc<NPROCS; iproc++) {
                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                        if (!pkgMatch && !reqPackage.equals(proc.mName)) {
                            continue;
                        }
                        if (activeOnly && !proc.isInUse()) {
                            pw.print("      (Not active: ");
                                    pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")");
@@ -1787,7 +1803,11 @@ public final class ProcessStats implements Parcelable {
                        }
                        pw.print("      Process ");
                        pw.print(pkgState.mProcesses.keyAt(iproc));
                        pw.print(" (");
                        if (proc.mCommonProcess.mMultiPackage) {
                            pw.print(" (multi, ");
                        } else {
                            pw.print(" (unique, ");
                        }
                        pw.print(proc.mDurationsTableSize);
                        pw.print(" entries)");
                        pw.println(":");
@@ -1801,6 +1821,9 @@ public final class ProcessStats implements Parcelable {
                    ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
                    for (int iproc=0; iproc<NPROCS; iproc++) {
                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                        if (!pkgMatch && !reqPackage.equals(proc.mName)) {
                            continue;
                        }
                        if (activeOnly && !proc.isInUse()) {
                            continue;
                        }
@@ -1811,6 +1834,9 @@ public final class ProcessStats implements Parcelable {
                }
                for (int isvc=0; isvc<NSRVS; isvc++) {
                    ServiceState svc = pkgState.mServices.valueAt(isvc);
                    if (!pkgMatch && !reqPackage.equals(svc.mProcessName)) {
                        continue;
                    }
                    if (activeOnly && !svc.isInUse()) {
                        pw.print("      (Not active: ");
                                pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")");
@@ -1840,12 +1866,15 @@ public final class ProcessStats implements Parcelable {
                        if (svc.mOwner != null) {
                            pw.print("        mOwner="); pw.println(svc.mOwner);
                        }
                        if (svc.mStarted || svc.mRestarting) {
                            pw.print("        mStarted="); pw.print(svc.mStarted);
                            pw.print(" mRestarting="); pw.println(svc.mRestarting);
                        }
                    }
                }
            }
        }

        if (reqPackage == null) {
        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
        printedHeader = false;
        int numShownProcs = 0, numTotalProcs = 0;
@@ -1860,10 +1889,20 @@ public final class ProcessStats implements Parcelable {
                        && proc.mPssTableSize == 0) {
                    continue;
                }
                if (!proc.mMultiPackage) {
                    continue;
                }
                if (reqPackage != null && !reqPackage.equals(procName)
                        && !reqPackage.equals(proc.mPackage)) {
                    continue;
                }
                numShownProcs++;
                    if (!printedHeader) {
                if (sepNeeded) {
                    pw.println();
                        pw.println("Per-Process Stats:");
                }
                sepNeeded = true;
                if (!printedHeader) {
                    pw.println("Multi-Package Common Processes:");
                    printedHeader = true;
                }
                if (activeOnly && !proc.isInUse()) {
@@ -1878,28 +1917,24 @@ public final class ProcessStats implements Parcelable {
                        ALL_PROC_STATES, now);
                dumpProcessPss(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
                        ALL_PROC_STATES);
                    if (dumpAll) {
                dumpProcessInternalLocked(pw, "        ", proc, dumpAll);
            }
        }
            }
        if (dumpAll) {
            pw.println();
            pw.print("  Total procs: "); pw.print(numShownProcs);
                    pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
        }

        if (sepNeeded) {
            pw.println();
        }
        if (dumpSummary) {
            pw.println("Summary:");
            dumpSummaryLocked(pw, reqPackage, now, activeOnly);
        } else {
            dumpTotalsLocked(pw, now);
        }
        } else {
            pw.println();
            dumpTotalsLocked(pw, now);
        }

        if (dumpAll) {
            pw.println();
@@ -2031,17 +2066,20 @@ public final class ProcessStats implements Parcelable {
    public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates,
            int[] procStates, int sortProcStates[], long now, String reqPackage,
            boolean activeOnly) {
        ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
        final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
        final ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
        for (int ip=0; ip<pkgMap.size(); ip++) {
            if (reqPackage != null && !reqPackage.equals(pkgMap.keyAt(ip))) {
            final String pkgName = pkgMap.keyAt(ip);
            final SparseArray<PackageState> procs = pkgMap.valueAt(ip);
            for (int iu=0; iu<procs.size(); iu++) {
                final PackageState state = procs.valueAt(iu);
                final int NPROCS = state.mProcesses.size();
                final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
                for (int iproc=0; iproc<NPROCS; iproc++) {
                    final ProcessState proc = state.mProcesses.valueAt(iproc);
                    if (!pkgMatch && !reqPackage.equals(proc.mName)) {
                        continue;
                    }
            SparseArray<PackageState> procs = pkgMap.valueAt(ip);
            for (int iu=0; iu<procs.size(); iu++) {
                PackageState state = procs.valueAt(iu);
                for (int iproc=0; iproc<state.mProcesses.size(); iproc++) {
                    ProcessState proc = state.mProcesses.valueAt(iproc);
                    if (activeOnly && !proc.isInUse()) {
                        continue;
                    }
@@ -2601,23 +2639,35 @@ public final class ProcessStats implements Parcelable {
            }
        }

        void incStartedServices(int memFactor, long now) {
        void incStartedServices(int memFactor, long now, String serviceName) {
            if (false) {
                RuntimeException here = new RuntimeException("here");
                here.fillInStackTrace();
                Slog.d(TAG, "incStartedServices: " + this + " service=" + serviceName
                        + " to " + (mNumStartedServices+1), here);
            }
            if (mCommonProcess != this) {
                mCommonProcess.incStartedServices(memFactor, now);
                mCommonProcess.incStartedServices(memFactor, now, serviceName);
            }
            mNumStartedServices++;
            if (mNumStartedServices == 1 && mCurState == STATE_NOTHING) {
                setState(STATE_NOTHING, memFactor, now, null);
                setState(STATE_SERVICE_RESTARTING + (memFactor*STATE_COUNT), now);
            }
        }

        void decStartedServices(int memFactor, long now) {
        void decStartedServices(int memFactor, long now, String serviceName) {
            if (false) {
                RuntimeException here = new RuntimeException("here");
                here.fillInStackTrace();
                Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName
                        + " to " + (mNumStartedServices-1), here);
            }
            if (mCommonProcess != this) {
                mCommonProcess.decStartedServices(memFactor, now);
                mCommonProcess.decStartedServices(memFactor, now, serviceName);
            }
            mNumStartedServices--;
            if (mNumStartedServices == 0 && mCurState == STATE_SERVICE_RESTARTING) {
                setState(STATE_NOTHING, memFactor, now, null);
            if (mNumStartedServices == 0 && (mCurState%STATE_COUNT) == STATE_SERVICE_RESTARTING) {
                setState(STATE_NOTHING, now);
            } else if (mNumStartedServices < 0) {
                Slog.wtfStack(TAG, "Proc started services underrun: pkg="
                        + mPackage + " uid=" + mUid + " name=" + mName);
@@ -2873,6 +2923,8 @@ public final class ProcessStats implements Parcelable {
        public int mRunState = STATE_NOTHING;
        long mRunStartTime;

        boolean mStarted;
        boolean mRestarting;
        int mStartedCount;
        public int mStartedState = STATE_NOTHING;
        long mStartedStartTime;
@@ -2902,10 +2954,9 @@ public final class ProcessStats implements Parcelable {
                    // There was already an old owner, reset this object for its
                    // new owner.
                    mOwner = newOwner;
                    if (mStartedState != STATE_NOTHING || mBoundState != STATE_NOTHING
                            || mExecState != STATE_NOTHING) {
                    if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
                        long now = SystemClock.uptimeMillis();
                        if (mStartedState != STATE_NOTHING) {
                        if (mStarted) {
                            if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
                                    + " from " + mOwner + " while started: pkg="
                                    + mPackage + " service=" + mName + " proc=" + mProc);
@@ -2931,10 +2982,9 @@ public final class ProcessStats implements Parcelable {
        public void clearCurrentOwner(Object owner, boolean silently) {
            if (mOwner == owner) {
                mProc.decActiveServices(mName);
                if (mStartedState != STATE_NOTHING || mBoundState != STATE_NOTHING
                        || mExecState != STATE_NOTHING) {
                if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
                    long now = SystemClock.uptimeMillis();
                    if (mStartedState != STATE_NOTHING) {
                    if (mStarted) {
                        if (!silently) {
                            Slog.wtfStack(TAG, "Service owner " + owner
                                    + " cleared while started: pkg=" + mPackage + " service="
@@ -3042,7 +3092,18 @@ public final class ProcessStats implements Parcelable {
            if (mOwner == null) {
                Slog.wtf(TAG, "Starting service " + this + " without owner");
            }
            mStarted = started;
            updateStartedState(memFactor, now);
        }

        public void setRestarting(boolean restarting, int memFactor, long now) {
            mRestarting = restarting;
            updateStartedState(memFactor, now);
        }

        void updateStartedState(int memFactor, long now) {
            final boolean wasStarted = mStartedState != STATE_NOTHING;
            final boolean started = mStarted || mRestarting;
            final int state = started ? memFactor : STATE_NOTHING;
            if (mStartedState != state) {
                if (mStartedState != STATE_NOTHING) {
@@ -3056,9 +3117,9 @@ public final class ProcessStats implements Parcelable {
                mProc = mProc.pullFixedProc(mPackage);
                if (wasStarted != started) {
                    if (started) {
                        mProc.incStartedServices(memFactor, now);
                        mProc.incStartedServices(memFactor, now, mName);
                    } else {
                        mProc.decStartedServices(memFactor, now);
                        mProc.decStartedServices(memFactor, now, mName);
                    }
                }
                updateRunning(memFactor, now);
+38 −14
Original line number Diff line number Diff line
@@ -1187,6 +1187,7 @@ public final class ActiveServices {
        if (!mRestartingServices.contains(r)) {
            r.createdFromFg = false;
            mRestartingServices.add(r);
            r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
        }

        r.cancelNotification();
@@ -1220,6 +1221,9 @@ public final class ActiveServices {
        if (removed || callingUid != r.appInfo.uid) {
            r.resetRestartCounter();
        }
        if (removed) {
            r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis());
        }
        mAm.mHandler.removeCallbacks(r.restarter);
        return true;
    }
@@ -1243,7 +1247,9 @@ public final class ActiveServices {

        // We are now bringing the service up, so no longer in the
        // restarting state.
        mRestartingServices.remove(r);
        if (mRestartingServices.remove(r)) {
            r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis());
        }

        // Make sure this service is no longer considered delayed, we are starting it now.
        if (r.delayed) {
@@ -1581,6 +1587,7 @@ public final class ActiveServices {
            }
            r.app.services.remove(r);
            if (r.app.thread != null) {
                updateServiceForegroundLocked(r.app, false);
                try {
                    bumpServiceExecutingLocked(r, false, "destroy");
                    mDestroyingServices.add(r);
@@ -1591,7 +1598,6 @@ public final class ActiveServices {
                            + r.shortName, e);
                    serviceProcessGoneLocked(r);
                }
                updateServiceForegroundLocked(r.app, false);
            } else {
                if (DEBUG_SERVICE) Slog.v(
                    TAG, "Removed service that has no process: " + r);
@@ -1816,6 +1822,9 @@ public final class ActiveServices {
                    r.tracker = null;
                }
            }
            if (finishing) {
                r.app = null;
            }
        }
    }

@@ -1960,8 +1969,7 @@ public final class ActiveServices {
        }
    }

    final void killServicesLocked(ProcessRecord app,
            boolean allowRestart) {
    final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
        // Report disconnected services.
        if (false) {
            // XXX we are letting the client link to the service for
@@ -1990,16 +1998,8 @@ public final class ActiveServices {
            }
        }

        // Clean up any connections this application has to other services.
        for (int i=app.connections.size()-1; i>=0; i--) {
            ConnectionRecord r = app.connections.valueAt(i);
            removeConnectionLocked(r, app, null);
        }
        app.connections.clear();

        // First clear app state from services.
        for (int i=app.services.size()-1; i>=0; i--) {
            // Any services running in the application need to be placed
            // back in the pending list.
            ServiceRecord sr = app.services.valueAt(i);
            synchronized (sr.stats.getBatteryStats()) {
                sr.stats.stopLaunchedLocked();
@@ -2020,8 +2020,21 @@ public final class ActiveServices {
                b.binder = null;
                b.requested = b.received = b.hasBound = false;
            }
        }

            if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
        // Clean up any connections this application has to other services.
        for (int i=app.connections.size()-1; i>=0; i--) {
            ConnectionRecord r = app.connections.valueAt(i);
            removeConnectionLocked(r, app, null);
        }
        app.connections.clear();

        // Now do remaining service cleanup.
        for (int i=app.services.size()-1; i>=0; i--) {
            // Any services running in the application may need to be placed
            // back in the pending list.
            ServiceRecord sr = app.services.valueAt(i);
            if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
                    &ApplicationInfo.FLAG_PERSISTENT) == 0) {
                Slog.w(TAG, "Service crashed " + sr.crashCount
                        + " times, stopping: " + sr);
@@ -2054,6 +2067,17 @@ public final class ActiveServices {

        if (!allowRestart) {
            app.services.clear();

            // Make sure there are no more restarting services for this process.
            for (int i=mRestartingServices.size()-1; i>=0; i--) {
                ServiceRecord r = mRestartingServices.get(i);
                if (r.processName.equals(app.processName) &&
                        r.serviceInfo.applicationInfo.uid == app.info.uid) {
                    mRestartingServices.remove(i);
                    r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
        }

        // Make sure we have no more records on the stopping list.
+19 −7
Original line number Diff line number Diff line
@@ -11905,6 +11905,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        boolean dumpDalvik = false;
        boolean oomOnly = false;
        boolean isCompact = false;
        boolean localOnly = false;
        
        int opti = 0;
        while (opti < args.length) {
@@ -11923,12 +11924,15 @@ public final class ActivityManagerService extends ActivityManagerNative
                isCompact = true;
            } else if ("--oom".equals(opt)) {
                oomOnly = true;
            } else if ("--local".equals(opt)) {
                localOnly = true;
            } else if ("-h".equals(opt)) {
                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
                pw.println("  -a: include all available information for each process.");
                pw.println("  -d: include dalvik details when dumping process details.");
                pw.println("  -c: dump in a compact machine-parseable representation.");
                pw.println("  --oom: only show processes organized by oom adj.");
                pw.println("  --local: only collect details locally, don't call process.");
                pw.println("If [process] is specified it can be the name or ");
                pw.println("pid of a specific process to dump.");
                return;
@@ -12045,6 +12049,13 @@ public final class ActivityManagerService extends ActivityManagerNative
                    mi.dalvikPrivateDirty = (int)tmpLong[0];
                }
                if (dumpDetails) {
                    if (localOnly) {
                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
                        if (isCheckinRequest) {
                            pw.println();
                        }
                    } else {
                        try {
                            pw.flush();
                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
@@ -12056,6 +12067,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                            }
                        }
                    }
                }
                final long myTotalPss = mi.getTotalPss();
                final long myTotalUss = mi.getTotalUss();
+11 −21
Original line number Diff line number Diff line
@@ -750,9 +750,6 @@ public final class ProcessStatsService extends IProcessStats.Stub {
                    return;
                } else {
                    // Not an option, last argument must be a package name.
                    try {
                        IPackageManager pm = AppGlobals.getPackageManager();
                        if (pm.getPackageUid(arg, UserHandle.getCallingUserId()) >= 0) {
                    reqPackage = arg;
                    // Include all details, since we know we are only going to
                    // be dumping a smaller set of data.  In fact only the details
@@ -760,14 +757,6 @@ public final class ProcessStatsService extends IProcessStats.Stub {
                    // to dump anything at all when filtering by package.
                    dumpDetails = true;
                }
                    } catch (RemoteException e) {
                    }
                    if (reqPackage == null) {
                        pw.println("Unknown package: " + arg);
                        dumpHelp(pw);
                        return;
                    }
                }
            }
        }

@@ -816,13 +805,14 @@ public final class ProcessStatsService extends IProcessStats.Stub {
            }
            return;
        } else if (aggregateHours != 0) {
            pw.print("AGGREGATED OVER LAST "); pw.print(aggregateHours); pw.println(" HOURS:");
            dumpAggregatedStats(pw, aggregateHours, now, reqPackage, isCompact,
                    dumpDetails, dumpFullDetails, dumpAll, activeOnly);
            return;
        }

        boolean sepNeeded = false;
        if (!currentOnly || isCheckin) {
        if (dumpAll || isCheckin) {
            mWriteLock.lock();
            try {
                ArrayList<String> files = getCommittedFiles(0, false, !isCheckin);
@@ -882,11 +872,11 @@ public final class ProcessStatsService extends IProcessStats.Stub {
            }
        }
        if (!isCheckin) {
            if (dumpAll) {
            if (!currentOnly) {
                if (sepNeeded) {
                    pw.println();
                    pw.println("AGGREGATED OVER LAST 24 HOURS:");
                }
                pw.println("AGGREGATED OVER LAST 24 HOURS:");
                dumpAggregatedStats(pw, 24, now, reqPackage, isCompact,
                        dumpDetails, dumpFullDetails, dumpAll, activeOnly);
                pw.println();
@@ -901,8 +891,8 @@ public final class ProcessStatsService extends IProcessStats.Stub {
                } else {
                    if (sepNeeded) {
                        pw.println();
                        pw.println("CURRENT STATS:");
                    }
                    pw.println("CURRENT STATS:");
                    if (dumpDetails || dumpFullDetails) {
                        mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll,
                                activeOnly);
Loading