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

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

am d53710ce: Merge "Extend process observer to be usable for media routing." into jb-dev

* commit 'd53710ce':
  Extend process observer to be usable for media routing.
parents db50f4eb d53710ce
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1359,6 +1359,13 @@ public class ActivityManager {
         */
        public int lastTrimLevel;

        /**
         * Constant for {@link #importance}: this is a persistent process.
         * Only used when reporting to process observers.
         * @hide
         */
        public static final int IMPORTANCE_PERSISTENT = 50;

        /**
         * Constant for {@link #importance}: this process is running the
         * foreground UI.
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package android.app;
oneway interface IProcessObserver {

    void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities);
    void onImportanceChanged(int pid, int uid, int importance);
    void onProcessDied(int pid, int uid);

}
+145 −23
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    static final boolean DEBUG_VISBILITY = localLOGV || false;
    static final boolean DEBUG_PROCESSES = localLOGV || false;
    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
    static final boolean DEBUG_PROVIDER = localLOGV || false;
    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
@@ -764,8 +765,24 @@ public final class ActivityManagerService extends ActivityManagerNative
    boolean mAutoStopProfiler = false;
    String mOpenGlTraceApp = null;
    static class ProcessChangeItem {
        static final int CHANGE_ACTIVITIES = 1<<0;
        static final int CHANGE_IMPORTANCE= 1<<1;
        int changes;
        int uid;
        int pid;
        int importance;
        boolean foregroundActivities;
    }
    final RemoteCallbackList<IProcessObserver> mProcessObservers
            = new RemoteCallbackList<IProcessObserver>();
    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
    final ArrayList<ProcessChangeItem> mPendingProcessChanges
            = new ArrayList<ProcessChangeItem>();
    final ArrayList<ProcessChangeItem> mAvailProcessChanges
            = new ArrayList<ProcessChangeItem>();
    /**
     * Callback of last caller to {@link #requestPss}.
@@ -855,7 +872,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    static final int CLEAR_DNS_CACHE = 28;
    static final int UPDATE_HTTP_PROXY = 29;
    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
    static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
    static final int DISPATCH_PROCESSES_CHANGED = 31;
    static final int DISPATCH_PROCESS_DIED = 32;
    static final int REPORT_MEM_USAGE = 33;
@@ -1195,11 +1212,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
                break;
            }
            case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
                final int pid = msg.arg1;
                final int uid = msg.arg2;
                final boolean foregroundActivities = (Boolean) msg.obj;
                dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
            case DISPATCH_PROCESSES_CHANGED: {
                dispatchProcessesChanged();
                break;
            }
            case DISPATCH_PROCESS_DIED: {
@@ -2260,19 +2274,43 @@ public final class ActivityManagerService extends ActivityManagerNative
    void reportResumedActivityLocked(ActivityRecord r) {
        //Slog.i(TAG, "**** REPORT RESUME: " + r);
        
        final int identHash = System.identityHashCode(r);
        updateUsageStats(r, true);
    }
    private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
    private void dispatchProcessesChanged() {
        int N;
        synchronized (this) {
            N = mPendingProcessChanges.size();
            if (mActiveProcessChanges.length < N) {
                mActiveProcessChanges = new ProcessChangeItem[N];
            }
            mPendingProcessChanges.toArray(mActiveProcessChanges);
            mAvailProcessChanges.addAll(mPendingProcessChanges);
            mPendingProcessChanges.clear();
            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
        }
        int i = mProcessObservers.beginBroadcast();
        while (i > 0) {
            i--;
            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
            if (observer != null) {
                try {
                    observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
                    for (int j=0; j<N; j++) {
                        ProcessChangeItem item = mActiveProcessChanges[j];
                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
                                    + item.pid + " uid=" + item.uid + ": "
                                    + item.foregroundActivities);
                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
                                    item.foregroundActivities);
                        }
                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
                            observer.onImportanceChanged(item.pid, item.uid,
                                    item.importance);
                        }
                    }
                } catch (RemoteException e) {
                }
            }
@@ -10802,6 +10840,13 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
        }
        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
            ProcessChangeItem item = mPendingProcessChanges.get(i);
            if (item.pid == app.pid) {
                mPendingProcessChanges.remove(i);
                mAvailProcessChanges.add(item);
            }
        }
        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
        // If the caller is restarting this app, then leave it in its
@@ -13734,9 +13779,6 @@ public final class ActivityManagerService extends ActivityManagerNative
            return (app.curAdj=app.maxAdj);
        }
        final boolean hadForegroundActivities = app.foregroundActivities;
        app.foregroundActivities = false;
        app.keeping = false;
        app.systemNoUi = false;
@@ -13744,18 +13786,22 @@ public final class ActivityManagerService extends ActivityManagerNative
        // important to least, and assign an appropriate OOM adjustment.
        int adj;
        int schedGroup;
        boolean foregroundActivities = false;
        boolean interesting = false;
        BroadcastQueue queue;
        if (app == TOP_APP) {
            // The last app on the list is the foreground app.
            adj = ProcessList.FOREGROUND_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "top-activity";
            app.foregroundActivities = true;
            foregroundActivities = true;
            interesting = true;
        } else if (app.instrumentationClass != null) {
            // Don't want to kill running instrumentation.
            adj = ProcessList.FOREGROUND_APP_ADJ;
            schedGroup = Process.THREAD_GROUP_DEFAULT;
            app.adjType = "instrumentation";
            interesting = true;
        } else if ((queue = isReceivingBroadcast(app)) != null) {
            // An app that is currently receiving a broadcast also
            // counts as being in the foreground for OOM killer purposes.
@@ -13791,7 +13837,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        boolean hasStoppingActivities = false;
        // Examine all activities if not already foreground.
        if (!app.foregroundActivities && activitiesSize > 0) {
        if (!foregroundActivities && activitiesSize > 0) {
            for (int j = 0; j < activitiesSize; j++) {
                final ActivityRecord r = app.activities.get(j);
                if (r.visible) {
@@ -13802,7 +13848,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                    }
                    schedGroup = Process.THREAD_GROUP_DEFAULT;
                    app.hidden = false;
                    app.foregroundActivities = true;
                    foregroundActivities = true;
                    break;
                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -13810,13 +13856,13 @@ public final class ActivityManagerService extends ActivityManagerNative
                        app.adjType = "pausing";
                    }
                    app.hidden = false;
                    app.foregroundActivities = true;
                    foregroundActivities = true;
                } else if (r.state == ActivityState.STOPPING) {
                    // We will apply the actual adjustment later, because
                    // we want to allow this process to immediately go through
                    // any memory trimming that is in effect.
                    app.hidden = false;
                    app.foregroundActivities = true;
                    foregroundActivities = true;
                    hasStoppingActivities = true;
                }
            }
@@ -13839,6 +13885,10 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
        }
        if (app.foregroundServices) {
            interesting = true;
        }
        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
            // We don't want to kill the current heavy-weight process.
            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
@@ -14188,12 +14238,84 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
        }
        int importance = app.memImportance;
        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
            app.curAdj = adj;
            app.curSchedGroup = schedGroup;
            if (!interesting) {
                // For this reporting, if there is not something explicitly
                // interesting in this process then we will push it to the
                // background importance.
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
            } else if (adj >= ProcessList.HOME_APP_ADJ) {
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
            } else if (adj >= ProcessList.SERVICE_ADJ) {
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
            } else {
                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
            }
        }
        if (hadForegroundActivities != app.foregroundActivities) {
            mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
                    app.foregroundActivities).sendToTarget();
        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
        if (foregroundActivities != app.foregroundActivities) {
            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
        }
        if (changes != 0) {
            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
            app.memImportance = importance;
            app.foregroundActivities = foregroundActivities;
            int i = mPendingProcessChanges.size()-1;
            ProcessChangeItem item = null;
            while (i >= 0) {
                item = mPendingProcessChanges.get(i);
                if (item.pid == app.pid) {
                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
                    break;
                }
                i--;
            }
            if (i < 0) {
                // No existing item in pending changes; need a new one.
                final int NA = mAvailProcessChanges.size();
                if (NA > 0) {
                    item = mAvailProcessChanges.remove(NA-1);
                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
                } else {
                    item = new ProcessChangeItem();
                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
                }
                item.changes = 0;
                item.pid = app.pid;
                item.uid = app.info.uid;
                if (mPendingProcessChanges.size() == 0) {
                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
                            "*** Enqueueing dispatch processes changed!");
                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
                }
                mPendingProcessChanges.add(item);
            }
            item.changes |= changes;
            item.importance = importance;
            item.foregroundActivities = foregroundActivities;
            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
                    + Integer.toHexString(System.identityHashCode(item))
                    + " " + app.toShortString() + ": changes=" + item.changes
                    + " importance=" + item.importance
                    + " foreground=" + item.foregroundActivities
                    + " type=" + app.adjType + " source=" + app.adjSource
                    + " target=" + app.adjTarget);
        }
        return app.curRawAdj;
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ class ProcessRecord {
    int curSchedGroup;          // Currently desired scheduling class
    int setSchedGroup;          // Last set to background scheduling class
    int trimMemoryLevel;        // Last selected memory trimming level
    int memImportance;          // Importance constant computed from curAdj
    boolean serviceb;           // Process currently is on the service B list
    boolean keeping;            // Actively running code so don't kill due to that?
    boolean setIsForeground;    // Running foreground UI when last set?
+4 −0
Original line number Diff line number Diff line
@@ -395,6 +395,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                    pid, uid, foregroundActivities).sendToTarget();
        }

        @Override
        public void onImportanceChanged(int pid, int uid, int importance) {
        }

        @Override
        public void onProcessDied(int pid, int uid) {
            mHandler.obtainMessage(MSG_PROCESS_DIED, pid, uid).sendToTarget();