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;
}
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)));
}
}
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;
}
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;
}
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;
}
Aggregations