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

Commit 91268cf2 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

More work on process tracking.

Re-arranged code to be more flexible, now track
state of services, dump ordered list of running
processes while memory was critical and low.

Also rename battery stats service from "batteryinfo" to "batterystats".

Change-Id: I0f4f0c8d443c49d255cb84d0fc917e8ec18b152e
parent 756a53f4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

import android.os.BatteryStats;
import android.os.IBinder;
import com.android.internal.app.IUsageStats;
import com.android.internal.os.PkgUsageStats;
@@ -2210,7 +2211,7 @@ public class ActivityManager {
        pw.println();
        dumpService(pw, fd, "package", new String[] { packageName});
        pw.println();
        dumpService(pw, fd, "batteryinfo", new String[] { packageName});
        dumpService(pw, fd, BatteryStats.SERVICE_NAME, new String[] { packageName});
        pw.flush();
    }

+4 −1
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@ public abstract class BatteryStats implements Parcelable {

    private static final boolean LOCAL_LOGV = false;

    /** @hide */
    public static final String SERVICE_NAME = "batterystats";

    /**
     * A constant indicating a partial wake lock timer.
     */
+2 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Handler;
import android.os.INetworkManagementService;
@@ -347,7 +348,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub

        if (mBandwidthControlEnabled) {
            try {
                IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"))
                IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME))
                        .noteNetworkStatsEnabled();
            } catch (RemoteException e) {
            }
+3 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.os.BatteryStats;
import android.os.Handler;
import android.os.IVibratorService;
import android.os.PowerManager;
@@ -143,7 +144,8 @@ public class VibratorService extends IVibratorService.Stub
        mWakeLock.setReferenceCounted(true);

        mAppOpsService = IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE));
        mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
        mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
                BatteryStats.SERVICE_NAME));

        mVibrations = new LinkedList<Vibration>();

+112 −49
Original line number Diff line number Diff line
@@ -241,11 +241,14 @@ public final class ActiveServices {
        if (unscheduleServiceRestartLocked(r)) {
            if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
        }
        r.lastActivity = SystemClock.uptimeMillis();
        r.startRequested = true;
        if (r.tracker != null) {
            r.tracker.setStarted(true, mAm.mProcessTracker.getMemFactor(), r.lastActivity);
        }
        r.callStart = false;
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                service, neededGrants));
        r.lastActivity = SystemClock.uptimeMillis();
        synchronized (r.stats.getBatteryStats()) {
            r.stats.startRunningLocked();
        }
@@ -261,8 +264,12 @@ public final class ActiveServices {
            service.stats.stopRunningLocked();
        }
        service.startRequested = false;
        if (service.tracker != null) {
            service.tracker.setStarted(false, mAm.mProcessTracker.getMemFactor(),
                    SystemClock.uptimeMillis());
        }
        service.callStart = false;
        bringDownServiceLocked(service, false);
        bringDownServiceIfNeededLocked(service, false, false);
    }

    int stopServiceLocked(IApplicationThread caller, Intent service,
@@ -355,11 +362,15 @@ public final class ActiveServices {

            synchronized (r.stats.getBatteryStats()) {
                r.stats.stopRunningLocked();
            }
            r.startRequested = false;
                r.callStart = false;
            if (r.tracker != null) {
                r.tracker.setStarted(false, mAm.mProcessTracker.getMemFactor(),
                        SystemClock.uptimeMillis());
            }
            r.callStart = false;
            final long origId = Binder.clearCallingIdentity();
            bringDownServiceLocked(r, false);
            bringDownServiceIfNeededLocked(r, false, false);
            Binder.restoreCallingIdentity(origId);
            return true;
        }
@@ -489,6 +500,17 @@ public final class ActiveServices {
                        + s);
            }

            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
                s.lastActivity = SystemClock.uptimeMillis();
                if (!s.hasAutoCreateConnections()) {
                    // This is the first binding, let the tracker know.
                    if (s.tracker != null) {
                        s.tracker.setBound(true, mAm.mProcessTracker.getMemFactor(),
                                s.lastActivity);
                    }
                }
            }

            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
            ConnectionRecord c = new ConnectionRecord(b, activity,
                    connection, flags, clientLabel, clientIntent);
@@ -748,7 +770,12 @@ public final class ActiveServices {
                                sInfo.applicationInfo.uid, sInfo.packageName,
                                sInfo.name);
                    }
                    r = new ServiceRecord(mAm, ss, name, filter, sInfo, res);
                    ProcessTracker.ServiceState tracker = null;
                    if ((sInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
                        tracker = mAm.mProcessTracker.getServiceStateLocked(sInfo.packageName,
                                sInfo.applicationInfo.uid, sInfo.name);
                    }
                    r = new ServiceRecord(mAm, ss, name, filter, sInfo, res, tracker);
                    res.setService(r);
                    mServiceMap.putServiceByName(name, UserHandle.getUserId(r.appInfo.uid), r);
                    mServiceMap.putServiceByIntent(filter, UserHandle.getUserId(r.appInfo.uid), r);
@@ -798,7 +825,11 @@ public final class ActiveServices {
        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
                + why + " of " + r.shortName);
        long now = SystemClock.uptimeMillis();
        if (r.executeNesting == 0 && r.app != null) {
        if (r.executeNesting == 0) {
            if (r.tracker != null) {
                r.tracker.setExecuting(true, mAm.mProcessTracker.getMemFactor(), now);
            }
            if (r.app != null) {
                if (r.app.executingServices.size() == 0) {
                    Message msg = mAm.mHandler.obtainMessage(
                            ActivityManagerService.SERVICE_TIMEOUT_MSG);
@@ -807,6 +838,7 @@ public final class ActiveServices {
                }
                r.app.executingServices.add(r);
            }
        }
        r.executeNesting++;
        r.executingStart = now;
    }
@@ -991,7 +1023,7 @@ public final class ActiveServices {
                    + r.appInfo.uid + " for service "
                    + r.intent.getIntent() + ": user " + r.userId + " is stopped";
            Slog.w(TAG, msg);
            bringDownServiceLocked(r, true);
            bringDownServiceLocked(r);
            return msg;
        }

@@ -1045,7 +1077,7 @@ public final class ActiveServices {
                        + r.appInfo.uid + " for service "
                        + r.intent.getIntent() + ": process is bad";
                Slog.w(TAG, msg);
                bringDownServiceLocked(r, true);
                bringDownServiceLocked(r);
                return msg;
            }
            if (isolated) {
@@ -1167,27 +1199,30 @@ public final class ActiveServices {
        }
    }

    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
    private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
            boolean hasConn) {
        //Slog.i(TAG, "Bring down service:");
        //r.dump("  ");

        // Does it still need to run?
        if (!force && r.startRequested) {
            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) {
        if (r.startRequested) {
            return;
        }

        if (!knowConn) {
            hasConn = r.hasAutoCreateConnections();
        }
        if (hasConn) {
            return;
        }

        bringDownServiceLocked(r);
    }

    private final void bringDownServiceLocked(ServiceRecord r) {
        //Slog.i(TAG, "Bring down service:");
        //r.dump("  ");

        // Report to all of the connections that the service is no longer
        // available.
        for (int conni=r.connections.size()-1; conni>=0; conni--) {
@@ -1291,6 +1326,13 @@ public final class ActiveServices {
        if (r.restarter instanceof ServiceRestarter) {
           ((ServiceRestarter)r.restarter).setService(null);
        }

        int memFactor = mAm.mProcessTracker.getMemFactor();
        long now = SystemClock.uptimeMillis();
        if (r.tracker != null) {
            r.tracker.setStarted(false, memFactor, now);
            r.tracker.setBound(false, memFactor, now);
        }
    }

    void removeConnectionLocked(
@@ -1349,7 +1391,14 @@ public final class ActiveServices {
            }

            if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
                bringDownServiceLocked(s, false);
                boolean hasAutoCreate = s.hasAutoCreateConnections();
                if (!hasAutoCreate) {
                    if (s.tracker != null) {
                        s.tracker.setBound(false, mAm.mProcessTracker.getMemFactor(),
                                SystemClock.uptimeMillis());
                    }
                }
                bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
            }
        }
    }
@@ -1422,7 +1471,8 @@ public final class ActiveServices {
                + ", inStopping=" + inStopping + ", app=" + r.app);
        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
        r.executeNesting--;
        if (r.executeNesting <= 0 && r.app != null) {
        if (r.executeNesting <= 0) {
            if (r.app != null) {
                if (DEBUG_SERVICE) Slog.v(TAG,
                        "Nesting at 0 of " + r.shortName);
                r.app.executingServices.remove(r);
@@ -1439,6 +1489,11 @@ public final class ActiveServices {
                }
                mAm.updateOomAdjLocked(r.app);
            }
            if (r.tracker != null) {
                r.tracker.setExecuting(false, mAm.mProcessTracker.getMemFactor(),
                        SystemClock.uptimeMillis());
            }
        }
    }

    boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
@@ -1494,7 +1549,7 @@ public final class ActiveServices {
                sr.isolatedProc = null;
                mPendingServices.remove(i);
                i--;
                bringDownServiceLocked(sr, true);
                bringDownServiceLocked(sr);
            }
        }
    }
@@ -1545,7 +1600,7 @@ public final class ActiveServices {

        int N = services.size();
        for (int i=0; i<N; i++) {
            bringDownServiceLocked(services.get(i), true);
            bringDownServiceLocked(services.get(i));
        }
        return didSomething;
    }
@@ -1628,6 +1683,10 @@ public final class ActiveServices {
                sr.app = null;
                sr.isolatedProc = null;
                sr.executeNesting = 0;
                if (sr.tracker != null) {
                    sr.tracker.setExecuting(false, mAm.mProcessTracker.getMemFactor(),
                            SystemClock.uptimeMillis());
                }
                if (mStoppingServices.remove(sr)) {
                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
                }
@@ -1647,9 +1706,9 @@ public final class ActiveServices {
                            + " times, stopping: " + sr);
                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
                            sr.userId, sr.crashCount, sr.shortName, app.pid);
                    bringDownServiceLocked(sr, true);
                    bringDownServiceLocked(sr);
                } else if (!allowRestart) {
                    bringDownServiceLocked(sr, true);
                    bringDownServiceLocked(sr);
                } else {
                    boolean canceled = scheduleServiceRestartLocked(sr, true);

@@ -1659,9 +1718,13 @@ public final class ActiveServices {
                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
                        if (sr.pendingStarts.size() == 0) {
                            sr.startRequested = false;
                            if (numClients > 0) {
                            if (sr.tracker != null) {
                                sr.tracker.setStarted(false, mAm.mProcessTracker.getMemFactor(),
                                        SystemClock.uptimeMillis());
                            }
                            if (!sr.hasAutoCreateConnections()) {
                                // Whoops, no reason to restart!
                                bringDownServiceLocked(sr, true);
                                bringDownServiceLocked(sr);
                            }
                        }
                    }
Loading