Search in sources :

Example 26 with ArraySet

use of android.util.ArraySet in project platform_frameworks_base by android.

the class ActivityManagerService method computeOomAdjLocked.

private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now) {
    if (mAdjSeq == app.adjSeq) {
        // This adjustment has already been computed.
        return app.curRawAdj;
    }
    if (app.thread == null) {
        app.adjSeq = mAdjSeq;
        app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
        app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
        return (app.curAdj = app.curRawAdj = ProcessList.CACHED_APP_MAX_ADJ);
    }
    app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
    app.adjSource = null;
    app.adjTarget = null;
    app.empty = false;
    app.cached = false;
    final int activitiesSize = app.activities.size();
    if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
        // The max adjustment doesn't allow this app to be anything
        // below foreground, so it is not worth doing work for it.
        app.adjType = "fixed";
        app.adjSeq = mAdjSeq;
        app.curRawAdj = app.maxAdj;
        app.foregroundActivities = false;
        app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
        // System processes can do UI, and when they do we want to have
        // them trim their memory after the user leaves the UI.  To
        // facilitate this, here we need to determine whether or not it
        // is currently showing UI.
        app.systemNoUi = true;
        if (app == TOP_APP) {
            app.systemNoUi = false;
            app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
            app.adjType = "pers-top-activity";
        } else if (app.hasTopUi) {
            app.systemNoUi = false;
            app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
            app.adjType = "pers-top-ui";
        } else if (activitiesSize > 0) {
            for (int j = 0; j < activitiesSize; j++) {
                final ActivityRecord r = app.activities.get(j);
                if (r.visible) {
                    app.systemNoUi = false;
                }
            }
        }
        if (!app.systemNoUi) {
            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
        }
        return (app.curAdj = app.maxAdj);
    }
    app.systemNoUi = false;
    final int PROCESS_STATE_CUR_TOP = mTopProcessState;
    // Determine the importance of the process, starting with most
    // important to least, and assign an appropriate OOM adjustment.
    int adj;
    int schedGroup;
    int procState;
    boolean foregroundActivities = false;
    final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
    if (app == TOP_APP) {
        // The last app on the list is the foreground app.
        adj = ProcessList.FOREGROUND_APP_ADJ;
        schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
        app.adjType = "top-activity";
        foregroundActivities = true;
        procState = PROCESS_STATE_CUR_TOP;
    } else if (app.instrumentationClass != null) {
        // Don't want to kill running instrumentation.
        adj = ProcessList.FOREGROUND_APP_ADJ;
        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        app.adjType = "instrumentation";
        procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
    } else if (isReceivingBroadcastLocked(app, queues)) {
        // An app that is currently receiving a broadcast also
        // counts as being in the foreground for OOM killer purposes.
        // It's placed in a sched group based on the nature of the
        // broadcast as reflected by which queue it's active in.
        adj = ProcessList.FOREGROUND_APP_ADJ;
        schedGroup = (queues.contains(mFgBroadcastQueue)) ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
        app.adjType = "broadcast";
        procState = ActivityManager.PROCESS_STATE_RECEIVER;
    } else if (app.executingServices.size() > 0) {
        // An app that is currently executing a service callback also
        // counts as being in the foreground.
        adj = ProcessList.FOREGROUND_APP_ADJ;
        schedGroup = app.execServicesFg ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
        app.adjType = "exec-service";
        procState = ActivityManager.PROCESS_STATE_SERVICE;
    //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
    } else {
        // As far as we know the process is empty.  We may change our mind later.
        schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
        // At this point we don't actually know the adjustment.  Use the cached adj
        // value that the caller wants us to.
        adj = cachedAdj;
        procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
        app.cached = true;
        app.empty = true;
        app.adjType = "cch-empty";
    }
    // Examine all activities if not already foreground.
    if (!foregroundActivities && activitiesSize > 0) {
        int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
        for (int j = 0; j < activitiesSize; j++) {
            final ActivityRecord r = app.activities.get(j);
            if (r.app != app) {
                Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app + " instead of expected " + app);
                if (r.app == null || (r.app.uid == app.uid)) {
                    // Only fix things up when they look sane
                    r.app = app;
                } else {
                    continue;
                }
            }
            if (r.visible) {
                // App has a visible activity; only upgrade adjustment.
                if (adj > ProcessList.VISIBLE_APP_ADJ) {
                    adj = ProcessList.VISIBLE_APP_ADJ;
                    app.adjType = "visible";
                }
                if (procState > PROCESS_STATE_CUR_TOP) {
                    procState = PROCESS_STATE_CUR_TOP;
                }
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                app.cached = false;
                app.empty = false;
                foregroundActivities = true;
                if (r.task != null && minLayer > 0) {
                    final int layer = r.task.mLayerRank;
                    if (layer >= 0 && minLayer > layer) {
                        minLayer = layer;
                    }
                }
                break;
            } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
                if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                    app.adjType = "pausing";
                }
                if (procState > PROCESS_STATE_CUR_TOP) {
                    procState = PROCESS_STATE_CUR_TOP;
                }
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                app.cached = false;
                app.empty = false;
                foregroundActivities = true;
            } else if (r.state == ActivityState.STOPPING) {
                if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                    app.adjType = "stopping";
                }
                // processes and they should soon all go into the cached state.
                if (!r.finishing) {
                    if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
                        procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
                    }
                }
                app.cached = false;
                app.empty = false;
                foregroundActivities = true;
            } else {
                if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
                    procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
                    app.adjType = "cch-act";
                }
            }
        }
        if (adj == ProcessList.VISIBLE_APP_ADJ) {
            adj += minLayer;
        }
    }
    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
        if (app.foregroundServices) {
            // The user is aware of this app, so make it visible.
            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
            app.cached = false;
            app.adjType = "fg-service";
            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        } else if (app.forcingToForeground != null) {
            // The user is aware of this app, so make it visible.
            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
            app.cached = false;
            app.adjType = "force-fg";
            app.adjSource = app.forcingToForeground;
            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        }
    }
    if (app == mHeavyWeightProcess) {
        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
            // We don't want to kill the current heavy-weight process.
            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.cached = false;
            app.adjType = "heavy";
        }
        if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
            procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
        }
    }
    if (app == mHomeProcess) {
        if (adj > ProcessList.HOME_APP_ADJ) {
            // This process is hosting what we currently consider to be the
            // home app, so we don't want to let it go into the background.
            adj = ProcessList.HOME_APP_ADJ;
            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.cached = false;
            app.adjType = "home";
        }
        if (procState > ActivityManager.PROCESS_STATE_HOME) {
            procState = ActivityManager.PROCESS_STATE_HOME;
        }
    }
    if (app == mPreviousProcess && app.activities.size() > 0) {
        if (adj > ProcessList.PREVIOUS_APP_ADJ) {
            // This was the previous process that showed UI to the user.
            // We want to try to keep it around more aggressively, to give
            // a good experience around switching between two apps.
            adj = ProcessList.PREVIOUS_APP_ADJ;
            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.cached = false;
            app.adjType = "previous";
        }
        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
        }
    }
    if (false)
        Slog.i(TAG, "OOM " + app + ": initial adj=" + adj + " reason=" + app.adjType);
    // By default, we use the computed adjustment.  It may be changed if
    // there are applications dependent on our services or providers, but
    // this gives us a baseline and makes sure we don't get into an
    // infinite recursion.
    app.adjSeq = mAdjSeq;
    app.curRawAdj = adj;
    app.hasStartedServices = false;
    if (mBackupTarget != null && app == mBackupTarget.app) {
        // If possible we want to avoid killing apps while they're being backed up
        if (adj > ProcessList.BACKUP_APP_ADJ) {
            if (DEBUG_BACKUP)
                Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
            adj = ProcessList.BACKUP_APP_ADJ;
            if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
                procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
            }
            app.adjType = "backup";
            app.cached = false;
        }
        if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
            procState = ActivityManager.PROCESS_STATE_BACKUP;
        }
    }
    boolean mayBeTop = false;
    for (int is = app.services.size() - 1; is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); is--) {
        ServiceRecord s = app.services.valueAt(is);
        if (s.startRequested) {
            app.hasStartedServices = true;
            if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
                procState = ActivityManager.PROCESS_STATE_SERVICE;
            }
            if (app.hasShownUi && app != mHomeProcess) {
                // debug and understand what is going on.
                if (adj > ProcessList.SERVICE_ADJ) {
                    app.adjType = "cch-started-ui-services";
                }
            } else {
                if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
                    // of the background processes.
                    if (adj > ProcessList.SERVICE_ADJ) {
                        adj = ProcessList.SERVICE_ADJ;
                        app.adjType = "started-services";
                        app.cached = false;
                    }
                }
                // even though the service no longer has an impact.
                if (adj > ProcessList.SERVICE_ADJ) {
                    app.adjType = "cch-started-services";
                }
            }
        }
        for (int conni = s.connections.size() - 1; conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); conni--) {
            ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
            for (int i = 0; i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); i++) {
                // XXX should compute this based on the max of
                // all connected clients.
                ConnectionRecord cr = clist.get(i);
                if (cr.binding.client == app) {
                    // Binding to ourself is not interesting.
                    continue;
                }
                if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) {
                    ProcessRecord client = cr.binding.client;
                    int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
                    int clientProcState = client.curProcState;
                    if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
                        // If the other app is cached for any reason, for purposes here
                        // we are going to consider it empty.  The specific cached state
                        // doesn't propagate except under certain conditions.
                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
                    }
                    String adjType = null;
                    if ((cr.flags & Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
                        // this guy more like a started service.
                        if (app.hasShownUi && app != mHomeProcess) {
                            // debug and understand what is going on.
                            if (adj > clientAdj) {
                                adjType = "cch-bound-ui-services";
                            }
                            app.cached = false;
                            clientAdj = adj;
                            clientProcState = procState;
                        } else {
                            if (now >= (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
                                // to help debug and undertand what is going on.
                                if (adj > clientAdj) {
                                    adjType = "cch-bound-services";
                                }
                                clientAdj = adj;
                            }
                        }
                    }
                    if (adj > clientAdj) {
                        // memory.
                        if (app.hasShownUi && app != mHomeProcess && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                            adjType = "cch-bound-ui-services";
                        } else {
                            if ((cr.flags & (Context.BIND_ABOVE_CLIENT | Context.BIND_IMPORTANT)) != 0) {
                                adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
                            } else if ((cr.flags & Context.BIND_NOT_VISIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                            } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
                                adj = clientAdj;
                            } else {
                                if (adj > ProcessList.VISIBLE_APP_ADJ) {
                                    adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
                                }
                            }
                            if (!client.cached) {
                                app.cached = false;
                            }
                            adjType = "service";
                        }
                    }
                    if ((cr.flags & Context.BIND_NOT_FOREGROUND) == 0) {
                        // foreground work.
                        if (client.curSchedGroup > schedGroup) {
                            if ((cr.flags & Context.BIND_IMPORTANT) != 0) {
                                schedGroup = client.curSchedGroup;
                            } else {
                                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                            }
                        }
                        if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
                            if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
                                // Special handling of clients who are in the top state.
                                // We *may* want to consider this process to be in the
                                // top state as well, but only if there is not another
                                // reason for it to be running.  Being on the top is a
                                // special state, meaning you are specifically running
                                // for the current top app.  If the process is already
                                // running in the background for some other reason, it
                                // is more important to continue considering it to be
                                // in the background state.
                                mayBeTop = true;
                                clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
                            } else {
                                // give them the best state after that.
                                if ((cr.flags & Context.BIND_FOREGROUND_SERVICE) != 0) {
                                    clientProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                                } else if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE && (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) != 0) {
                                    clientProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                                } else {
                                    clientProcState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
                                }
                            }
                        }
                    } else {
                        if (clientProcState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
                            clientProcState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
                        }
                    }
                    if (procState > clientProcState) {
                        procState = clientProcState;
                    }
                    if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND && (cr.flags & Context.BIND_SHOWING_UI) != 0) {
                        app.pendingUiClean = true;
                    }
                    if (adjType != null) {
                        app.adjType = adjType;
                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE;
                        app.adjSource = cr.binding.client;
                        app.adjSourceProcState = clientProcState;
                        app.adjTarget = s.name;
                    }
                }
                if ((cr.flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
                    app.treatLikeActivity = true;
                }
                final ActivityRecord a = cr.activity;
                if ((cr.flags & Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
                    if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible || a.state == ActivityState.RESUMED || a.state == ActivityState.PAUSING)) {
                        adj = ProcessList.FOREGROUND_APP_ADJ;
                        if ((cr.flags & Context.BIND_NOT_FOREGROUND) == 0) {
                            if ((cr.flags & Context.BIND_IMPORTANT) != 0) {
                                schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
                            } else {
                                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                            }
                        }
                        app.cached = false;
                        app.adjType = "service";
                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE;
                        app.adjSource = a;
                        app.adjSourceProcState = procState;
                        app.adjTarget = s.name;
                    }
                }
            }
        }
    }
    for (int provi = app.pubProviders.size() - 1; provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); provi--) {
        ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
        for (int i = cpr.connections.size() - 1; i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > ActivityManager.PROCESS_STATE_TOP); i--) {
            ContentProviderConnection conn = cpr.connections.get(i);
            ProcessRecord client = conn.client;
            if (client == app) {
                // Being our own client is not interesting.
                continue;
            }
            int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
            int clientProcState = client.curProcState;
            if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
                // If the other app is cached for any reason, for purposes here
                // we are going to consider it empty.
                clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
            }
            if (adj > clientAdj) {
                if (app.hasShownUi && app != mHomeProcess && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                    app.adjType = "cch-ui-provider";
                } else {
                    adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
                    app.adjType = "provider";
                }
                app.cached &= client.cached;
                app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_PROVIDER_IN_USE;
                app.adjSource = client;
                app.adjSourceProcState = clientProcState;
                app.adjTarget = cpr.name;
            }
            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
                    // Special handling of clients who are in the top state.
                    // We *may* want to consider this process to be in the
                    // top state as well, but only if there is not another
                    // reason for it to be running.  Being on the top is a
                    // special state, meaning you are specifically running
                    // for the current top app.  If the process is already
                    // running in the background for some other reason, it
                    // is more important to continue considering it to be
                    // in the background state.
                    mayBeTop = true;
                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
                } else {
                    // Special handling for above-top states (persistent
                    // processes).  These should not bring the current process
                    // into the top state, since they are not on top.  Instead
                    // give them the best state after that.
                    clientProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                }
            }
            if (procState > clientProcState) {
                procState = clientProcState;
            }
            if (client.curSchedGroup > schedGroup) {
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
            }
        }
        // FOREGROUND_APP_ADJ.
        if (cpr.hasExternalProcessHandles()) {
            if (adj > ProcessList.FOREGROUND_APP_ADJ) {
                adj = ProcessList.FOREGROUND_APP_ADJ;
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                app.cached = false;
                app.adjType = "provider";
                app.adjTarget = cpr.name;
            }
            if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
            }
        }
    }
    if (app.lastProviderTime > 0 && (app.lastProviderTime + CONTENT_PROVIDER_RETAIN_TIME) > now) {
        if (adj > ProcessList.PREVIOUS_APP_ADJ) {
            adj = ProcessList.PREVIOUS_APP_ADJ;
            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.cached = false;
            app.adjType = "provider";
        }
        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
        }
    }
    if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
        // to the top state.
        switch(procState) {
            case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
            case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
            case ActivityManager.PROCESS_STATE_SERVICE:
                // These all are longer-term states, so pull them up to the top
                // of the background states, but not all the way to the top state.
                procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                break;
            default:
                // Otherwise, top is a better choice, so take it.
                procState = ActivityManager.PROCESS_STATE_TOP;
                break;
        }
    }
    if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
        if (app.hasClientActivities) {
            // This is a cached process, but with client activities.  Mark it so.
            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
            app.adjType = "cch-client-act";
        } else if (app.treatLikeActivity) {
            // This is a cached process, but somebody wants us to treat it like it has
            // an activity, okay!
            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
            app.adjType = "cch-as-act";
        }
    }
    if (adj == ProcessList.SERVICE_ADJ) {
        if (doingAll) {
            app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs / 3);
            mNewNumServiceProcs++;
            //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
            if (!app.serviceb) {
                // keep launcher over it.
                if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
                    app.serviceHighRam = true;
                    app.serviceb = true;
                //Slog.i(TAG, "ADJ " + app + " high ram!");
                } else {
                    mNewNumAServiceProcs++;
                //Slog.i(TAG, "ADJ " + app + " not high ram!");
                }
            } else {
                app.serviceHighRam = false;
            }
        }
        if (app.serviceb) {
            adj = ProcessList.SERVICE_B_ADJ;
        }
    }
    app.curRawAdj = adj;
    //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
    if (adj > app.maxAdj) {
        adj = app.maxAdj;
        if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        }
    }
    // Do final modification to adj.  Everything we do between here and applying
    // the final setAdj must be done in this function, because we will also use
    // it when computing the final cached adj later.  Note that we don't need to
    // worry about this for max adj above, since max adj will always be used to
    // keep it out of the cached vaues.
    app.curAdj = app.modifyRawOomAdj(adj);
    app.curSchedGroup = schedGroup;
    app.curProcState = procState;
    app.foregroundActivities = foregroundActivities;
    return app.curRawAdj;
}
Also used : ArraySet(android.util.ArraySet) Point(android.graphics.Point)

Example 27 with ArraySet

use of android.util.ArraySet in project platform_frameworks_base by android.

the class UsageStatsService method cleanUpRemovedUsersLocked.

private void cleanUpRemovedUsersLocked() {
    final List<UserInfo> users = mUserManager.getUsers(true);
    if (users == null || users.size() == 0) {
        throw new IllegalStateException("There can't be no users");
    }
    ArraySet<String> toDelete = new ArraySet<>();
    String[] fileNames = mUsageStatsDir.list();
    if (fileNames == null) {
        // No users to delete.
        return;
    }
    toDelete.addAll(Arrays.asList(fileNames));
    final int userCount = users.size();
    for (int i = 0; i < userCount; i++) {
        final UserInfo userInfo = users.get(i);
        toDelete.remove(Integer.toString(userInfo.id));
    }
    final int deleteCount = toDelete.size();
    for (int i = 0; i < deleteCount; i++) {
        deleteRecursively(new File(mUsageStatsDir, toDelete.valueAt(i)));
    }
}
Also used : ArraySet(android.util.ArraySet) UserInfo(android.content.pm.UserInfo) File(java.io.File)

Example 28 with ArraySet

use of android.util.ArraySet in project platform_frameworks_base by android.

the class Vpn method createUserAndRestrictedProfilesRanges.

/**
     * Creates a {@link Set} of non-intersecting {@link UidRange} objects including all UIDs
     * associated with one user, and any restricted profiles attached to that user.
     *
     * <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided,
     * the UID ranges will match the app whitelist or blacklist specified there. Otherwise, all UIDs
     * in each user and profile will be included.
     *
     * @param userHandle The userId to create UID ranges for along with any of its restricted
     *                   profiles.
     * @param allowedApplications (optional) whitelist of applications to include.
     * @param disallowedApplications (optional) blacklist of applications to exclude.
     */
@VisibleForTesting
Set<UidRange> createUserAndRestrictedProfilesRanges(@UserIdInt int userHandle, @Nullable List<String> allowedApplications, @Nullable List<String> disallowedApplications) {
    final Set<UidRange> ranges = new ArraySet<>();
    // Assign the top-level user to the set of ranges
    addUserToRanges(ranges, userHandle, allowedApplications, disallowedApplications);
    // If the user can have restricted profiles, assign all its restricted profiles too
    if (canHaveRestrictedProfile(userHandle)) {
        final long token = Binder.clearCallingIdentity();
        List<UserInfo> users;
        try {
            users = UserManager.get(mContext).getUsers(true);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        for (UserInfo user : users) {
            if (user.isRestricted() && (user.restrictedProfileParentId == userHandle)) {
                addUserToRanges(ranges, user.id, allowedApplications, disallowedApplications);
            }
        }
    }
    return ranges;
}
Also used : ArraySet(android.util.ArraySet) UidRange(android.net.UidRange) UserInfo(android.content.pm.UserInfo) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 29 with ArraySet

use of android.util.ArraySet in project platform_frameworks_base by android.

the class UserController method unlockUserCleared.

boolean unlockUserCleared(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
    UserState uss;
    synchronized (mService) {
        // TODO Move this block outside of synchronized if it causes lock contention
        if (!StorageManager.isUserKeyUnlocked(userId)) {
            final UserInfo userInfo = getUserInfo(userId);
            final IMountService mountService = getMountService();
            try {
                // We always want to unlock user storage, even user is not started yet
                mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
            } catch (RemoteException | RuntimeException e) {
                Slog.w(TAG, "Failed to unlock: " + e.getMessage());
            }
        }
        // Bail if user isn't actually running, otherwise register the given
        // listener to watch for unlock progress
        uss = mStartedUsers.get(userId);
        if (uss == null) {
            notifyFinished(userId, listener);
            return false;
        } else {
            uss.mUnlockProgress.addListener(listener);
            uss.tokenProvided = (token != null);
        }
    }
    finishUserUnlocking(uss);
    final ArraySet<Integer> childProfilesToUnlock = new ArraySet<>();
    synchronized (mService) {
        // managed profiles under that user.
        for (int i = 0; i < mStartedUsers.size(); i++) {
            final int testUserId = mStartedUsers.keyAt(i);
            final UserInfo parent = getUserManager().getProfileParent(testUserId);
            if (parent != null && parent.id == userId && testUserId != userId) {
                Slog.d(TAG, "User " + testUserId + " (parent " + parent.id + "): attempting unlock because parent was just unlocked");
                childProfilesToUnlock.add(testUserId);
            }
        }
    }
    final int size = childProfilesToUnlock.size();
    for (int i = 0; i < size; i++) {
        maybeUnlockUser(childProfilesToUnlock.valueAt(i));
    }
    return true;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArraySet(android.util.ArraySet) IMountService(android.os.storage.IMountService) UserInfo(android.content.pm.UserInfo) RemoteException(android.os.RemoteException)

Example 30 with ArraySet

use of android.util.ArraySet in project platform_frameworks_base by android.

the class ManagedServices method loadComponentNamesFromSetting.

@NonNull
protected ArraySet<ComponentName> loadComponentNamesFromSetting(String settingName, int userId) {
    final ContentResolver cr = mContext.getContentResolver();
    String settingValue = Settings.Secure.getStringForUser(cr, settingName, userId);
    if (TextUtils.isEmpty(settingValue))
        return new ArraySet<>();
    String[] restored = settingValue.split(ENABLED_SERVICES_SEPARATOR);
    ArraySet<ComponentName> result = new ArraySet<>(restored.length);
    for (int i = 0; i < restored.length; i++) {
        ComponentName value = ComponentName.unflattenFromString(restored[i]);
        if (null != value) {
            result.add(value);
        }
    }
    return result;
}
Also used : ArraySet(android.util.ArraySet) ComponentName(android.content.ComponentName) ContentResolver(android.content.ContentResolver) NonNull(android.annotation.NonNull)

Aggregations

ArraySet (android.util.ArraySet)431 PublicKey (java.security.PublicKey)94 ComponentName (android.content.ComponentName)73 ArrayMap (android.util.ArrayMap)73 ArrayList (java.util.ArrayList)66 Pair (android.util.Pair)47 File (java.io.File)33 SSLContext (javax.net.ssl.SSLContext)32 Intent (android.content.Intent)30 RemoteException (android.os.RemoteException)29 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)28 ResolveInfo (android.content.pm.ResolveInfo)25 Point (android.graphics.Point)24 IOException (java.io.IOException)23 UserInfo (android.content.pm.UserInfo)21 X509Certificate (java.security.cert.X509Certificate)20 ContentResolver (android.content.ContentResolver)16 PackageManager (android.content.pm.PackageManager)15 NetworkPolicyManager.uidRulesToString (android.net.NetworkPolicyManager.uidRulesToString)15 SparseArray (android.util.SparseArray)15