Foreground Process&Background Process

本文探讨了操作系统启动过程中创建的不同类型的进程,包括与用户交互的前台进程及执行特定功能的后台进程。
When an operating system is booted, often several processes are created. Some of these are foreground processes, that is, processes that interact with (human) users and perform work for them. Others are background processes, which are not associated with particular users, but instead have some specific function. 
/media/fangqing/95b0e9e6-31e0-48d0-96fa-46599f44a68c/codessi/QSSI12/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval, boolean computeClients) { if (mAdjSeq == app.adjSeq) { if (app.adjSeq == app.completedAdjSeq) { // This adjustment has already been computed successfully. return false; } else { // The process is being computed, so there is a cycle. We cannot // rely on this process's state. app.containsCycle = true; return false; } } if (app.thread == null) { app.adjSeq = mAdjSeq; app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND); app.setCurProcState(PROCESS_STATE_CACHED_EMPTY); app.curAdj = ProcessList.CACHED_APP_MAX_ADJ; app.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ); app.completedAdjSeq = app.adjSeq; app.curCapability = PROCESS_CAPABILITY_NONE; return false; } app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; app.adjSource = null; app.adjTarget = null; app.empty = false; app.setCached(false); app.shouldNotFreeze = false; final int appUid = app.info.uid; final int logUid = mService.mCurOomAdjUid; int prevAppAdj = app.curAdj; int prevProcState = app.getCurProcState(); int prevCapability = app.curCapability; 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. if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { mService.reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app); } app.adjType = "fixed"; app.adjSeq = mAdjSeq; app.setCurRawAdj(app.maxAdj); app.setHasForegroundActivities(false); app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); app.curCapability = PROCESS_CAPABILITY_ALL; app.setCurProcState(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 == topApp) { app.systemNoUi = false; app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP); app.adjType = "pers-top-activity"; } else if (app.hasTopUi()) { // sched group/proc state adjustment is below app.systemNoUi = false; app.adjType = "pers-top-ui"; } else if (app.getCachedHasVisibleActivities()) { app.systemNoUi = false; } if (!app.systemNoUi) { if (mService.mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) { // screen on, promote UI app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI); app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP); } else { // screen off, restrict UI scheduling app.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE); app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED); } } app.setCurRawProcState(app.getCurProcState()); app.curAdj = app.maxAdj; app.completedAdjSeq = app.adjSeq; // if curAdj is less than prevAppAdj, then this process was promoted return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState; } app.systemNoUi = false; final int PROCESS_STATE_CUR_TOP = mService.mAtmInternal.getTopProcessState(); // Determine the importance of the process, starting with most // important to least, and assign an appropriate OOM adjustment. int adj; int schedGroup; int procState; int cachedAdjSeq; int capability = 0; boolean foregroundActivities = false; if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) { // 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; if(mIsTopAppRenderThreadBoostEnabled) { if(mCurRenderThreadTid != app.renderThreadTid && app.renderThreadTid > 0) { mCurRenderThreadTid = app.renderThreadTid; if (mPerfBoost != null) { Slog.d(TAG, "TOP-APP: pid:" + app.pid + ", processName: " + app.processName + ", renderThreadTid: " + app.renderThreadTid); if (mPerfHandle >= 0) { mPerfBoost.perfLockRelease(); mPerfHandle = -1; } mPerfHandle = mPerfBoost.perfHint(BoostFramework.VENDOR_HINT_BOOST_RENDERTHREAD, app.processName, app.renderThreadTid, 1); Slog.d(TAG, "VENDOR_HINT_BOOST_RENDERTHREAD perfHint was called. mPerfHandle: " + mPerfHandle); } } } if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app); } } else if (app.runningRemoteAnimation) { adj = ProcessList.VISIBLE_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_TOP_APP; app.adjType = "running-remote-anim"; procState = PROCESS_STATE_CUR_TOP; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app); } } else if (app.getActiveInstrumentation() != null) { // Don't want to kill running instrumentation. adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; app.adjType = "instrumentation"; procState = PROCESS_STATE_FOREGROUND_SERVICE; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app); } } else if (app.getCachedIsReceivingBroadcast(mTmpBroadcastQueue)) { // 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 = (mTmpBroadcastQueue.contains(mService.mFgBroadcastQueue)) ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; app.adjType = "broadcast"; procState = ActivityManager.PROCESS_STATE_RECEIVER; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app); } } 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 = PROCESS_STATE_SERVICE; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app); } //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); } else if (app == topApp) { adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; app.adjType = "top-sleeping"; foregroundActivities = true; procState = PROCESS_STATE_CUR_TOP; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + 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 = PROCESS_STATE_CACHED_EMPTY; if (!app.containsCycle) { app.setCached(true); app.empty = true; app.adjType = "cch-empty"; } if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app); } } // Examine all activities if not already foreground. if (!foregroundActivities && app.getCachedHasActivities()) { app.computeOomAdjFromActivitiesIfNecessary(mTmpComputeOomAdjWindowCallback, adj, foregroundActivities, procState, schedGroup, appUid, logUid, PROCESS_STATE_CUR_TOP); adj = app.mCachedAdj; foregroundActivities = app.mCachedForegroundActivities; procState = app.mCachedProcState; schedGroup = app.mCachedSchedGroup; } if (procState > PROCESS_STATE_CACHED_RECENT && app.getCachedHasRecentTasks()) { procState = PROCESS_STATE_CACHED_RECENT; app.adjType = "cch-rec"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app); } } if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > PROCESS_STATE_FOREGROUND_SERVICE) { if (app.hasForegroundServices()) { // The user is aware of this app, so make it visible. adj = ProcessList.PERCEPTIBLE_APP_ADJ; procState = PROCESS_STATE_FOREGROUND_SERVICE; app.adjType = "fg-service"; app.setCached(false); schedGroup = ProcessList.SCHED_GROUP_DEFAULT; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + app.adjType + ": " + app + " "); } } else if (app.hasOverlayUi()) { // The process is display an overlay UI. adj = ProcessList.PERCEPTIBLE_APP_ADJ; procState = PROCESS_STATE_IMPORTANT_FOREGROUND; app.setCached(false); app.adjType = "has-overlay-ui"; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app); } } } // If the app was recently in the foreground and moved to a foreground service status, // allow it to get a higher rank in memory for some time, compared to other foreground // services so that it can finish performing any persistence/processing of in-memory state. if (app.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now || app.setProcState <= PROCESS_STATE_TOP)) { adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; app.adjType = "fg-service-act"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app); } } if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > PROCESS_STATE_TRANSIENT_BACKGROUND) { if (app.forcingToImportant != null) { // This is currently used for toasts... they are not interactive, and // we don't want them to cause the app to become fully foreground (and // thus out of background check), so we yes the best background level we can. adj = ProcessList.PERCEPTIBLE_APP_ADJ; procState = PROCESS_STATE_TRANSIENT_BACKGROUND; app.setCached(false); app.adjType = "force-imp"; app.adjSource = app.forcingToImportant; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app); } } } if (app.getCachedIsHeavyWeight()) { 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.setCached(false); app.adjType = "heavy"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app); } } if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; app.adjType = "heavy"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app); } } } if (app.getCachedIsHomeProcess()) { 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.setCached(false); app.adjType = "home"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app); } } if (procState > ActivityManager.PROCESS_STATE_HOME) { procState = ActivityManager.PROCESS_STATE_HOME; app.adjType = "home"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app); } } } if (app.getCachedIsPreviousProcess() && app.getCachedHasActivities()) { 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.setCached(false); app.adjType = "previous"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app); } } if (procState > PROCESS_STATE_LAST_ACTIVITY) { procState = PROCESS_STATE_LAST_ACTIVITY; app.adjType = "previous"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app); } } } 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. If we're re-evaluating due to cycles, use the previously computed // values. if (cycleReEval) { procState = Math.min(procState, app.getCurRawProcState()); adj = Math.min(adj, app.getCurRawAdj()); schedGroup = Math.max(schedGroup, app.getCurrentSchedulingGroup()); } app.setCurRawAdj(adj); app.setCurRawProcState(procState); app.hasStartedServices = false; app.adjSeq = mAdjSeq; final BackupRecord backupTarget = mService.mBackupTargets.get(app.userId); if (backupTarget != null && app == backupTarget.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 > PROCESS_STATE_TRANSIENT_BACKGROUND) { procState = PROCESS_STATE_TRANSIENT_BACKGROUND; } app.adjType = "backup"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app); } app.setCached(false); } if (procState > ActivityManager.PROCESS_STATE_BACKUP) { procState = ActivityManager.PROCESS_STATE_BACKUP; app.adjType = "backup"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app); } } } int capabilityFromFGS = 0; // capability from foreground service. for (int is = app.numberOfRunningServices() - 1; is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > PROCESS_STATE_TOP); is--) { ServiceRecord s = app.getRunningServiceAt(is); if (s.startRequested) { app.hasStartedServices = true; if (procState > PROCESS_STATE_SERVICE) { procState = PROCESS_STATE_SERVICE; app.adjType = "started-services"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to started service: " + app); } } if (!s.mKeepWarming && app.hasShownUi && !app.getCachedIsHomeProcess()) { // If this process has shown some UI, let it immediately // go to the LRU list because it may be pretty heavy with // UI stuff. We'll tag it with a label just to help // debug and understand what is going on. if (adj > ProcessList.SERVICE_ADJ) { app.adjType = "cch-started-ui-services"; } } else { if (s.mKeepWarming || now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { // This service has seen some activity within // recent memory, so we will keep its process ahead // of the background processes. if (adj > ProcessList.SERVICE_ADJ) { adj = ProcessList.SERVICE_ADJ; app.adjType = "started-services"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to started service: " + app); } app.setCached(false); } } // If we have let the service slide into the background // state, still have some text describing what it is doing // even though the service no longer has an impact. if (adj > ProcessList.SERVICE_ADJ) { app.adjType = "cch-started-services"; } } } if (s.isForeground) { final int fgsType = s.foregroundServiceType; if (s.mAllowWhileInUsePermissionInFgs) { capabilityFromFGS |= (fgsType & FOREGROUND_SERVICE_TYPE_LOCATION) != 0 ? PROCESS_CAPABILITY_FOREGROUND_LOCATION : 0; boolean enabled = false; try { enabled = mPlatformCompat.isChangeEnabled( CAMERA_MICROPHONE_CAPABILITY_CHANGE_ID, s.appInfo); } catch (RemoteException e) { } if (enabled) { capabilityFromFGS |= (fgsType & FOREGROUND_SERVICE_TYPE_CAMERA) != 0 ? PROCESS_CAPABILITY_FOREGROUND_CAMERA : 0; capabilityFromFGS |= (fgsType & FOREGROUND_SERVICE_TYPE_MICROPHONE) != 0 ? PROCESS_CAPABILITY_FOREGROUND_MICROPHONE : 0; } else { capabilityFromFGS |= PROCESS_CAPABILITY_FOREGROUND_CAMERA | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; } } } ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections(); for (int conni = serviceConnections.size() - 1; conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > PROCESS_STATE_TOP); conni--) { ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni); for (int i = 0; i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > 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 oneself is not interesting. continue; } boolean trackedProcState = false; ProcessRecord client = cr.binding.client; if (computeClients) { computeOomAdjLocked(client, cachedAdj, topApp, doingAll, now, cycleReEval, true); } else { client.setCurRawAdj(client.setAdj); client.setCurRawProcState(client.setProcState); } int clientAdj = client.getCurRawAdj(); int clientProcState = client.getCurRawProcState(); if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) { if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; } if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { capability |= client.curCapability; } if (clientProcState >= 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 = PROCESS_STATE_CACHED_EMPTY; } String adjType = null; if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { // Not doing bind OOM management, so treat // this guy more like a started service. if (app.hasShownUi && !app.getCachedIsHomeProcess()) { // If this process has shown some UI, let it immediately // go to the LRU list because it may be pretty heavy with // UI stuff. We'll tag it with a label just to help // debug and understand what is going on. if (adj > clientAdj) { adjType = "cch-bound-ui-services"; } app.setCached(false); clientAdj = adj; clientProcState = procState; } else { if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { // This service has not seen activity within // recent memory, so allow it to drop to the // LRU list if there is no other reason to keep // it around. We'll also tag it with a label just // to help debug and undertand what is going on. if (adj > clientAdj) { adjType = "cch-bound-services"; } clientAdj = adj; } } } if (adj > clientAdj) { // If this process has recently shown UI, and // the process that is binding to it is less // important than being visible, then we don't // care about the binding as much as we care // about letting this process get into the LRU // list to be killed and restarted if needed for // memory. if (app.hasShownUi && !app.getCachedIsHomeProcess() && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { adjType = "cch-bound-ui-services"; } } else { int newAdj; if ((cr.flags&(Context.BIND_ABOVE_CLIENT |Context.BIND_IMPORTANT)) != 0) { if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) { newAdj = clientAdj; } else { // make this service persistent newAdj = ProcessList.PERSISTENT_SERVICE_ADJ; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; procState = ActivityManager.PROCESS_STATE_PERSISTENT; cr.trackProcState(procState, mAdjSeq, now); trackedProcState = true; } } else if ((cr.flags & Context.BIND_NOT_PERCEPTIBLE) != 0 && clientAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && adj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { newAdj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ; } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { newAdj = ProcessList.PERCEPTIBLE_APP_ADJ; } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { newAdj = clientAdj; } else { if (adj > ProcessList.VISIBLE_APP_ADJ) { // TODO: Is this too limiting for apps bound from TOP? newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ); } else { newAdj = adj; } } if (!client.isCached()) { app.setCached(false); } if (adj > newAdj) { adj = newAdj; app.setCurRawAdj(adj); adjType = "service"; } } } if ((cr.flags & (Context.BIND_NOT_FOREGROUND | Context.BIND_IMPORTANT_BACKGROUND)) == 0) { // This will treat important bound services identically to // the top app, which may behave differently than generic // foreground work. final int curSchedGroup = client.getCurrentSchedulingGroup(); if (curSchedGroup > schedGroup) { if ((cr.flags&Context.BIND_IMPORTANT) != 0) { schedGroup = curSchedGroup; } else { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; } } if (clientProcState < PROCESS_STATE_TOP) { // 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 bound state after that. if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) { clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; ; } else if (mService.mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE && (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) != 0) { clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } else { clientProcState = PROCESS_STATE_IMPORTANT_FOREGROUND; } } else if (clientProcState == PROCESS_STATE_TOP) { // Go at most to BOUND_TOP, unless requested to elevate // to client's state. clientProcState = PROCESS_STATE_BOUND_TOP; boolean enabled = false; try { enabled = mPlatformCompat.isChangeEnabled( PROCESS_CAPABILITY_CHANGE_ID, client.info); } catch (RemoteException e) { } if (enabled) { if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { // TOP process passes all capabilities to the service. capability |= PROCESS_CAPABILITY_ALL; } else { // TOP process passes no capability to the service. } } else { // TOP process passes all capabilities to the service. capability |= PROCESS_CAPABILITY_ALL; } } } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) { if (clientProcState < PROCESS_STATE_TRANSIENT_BACKGROUND) { clientProcState = PROCESS_STATE_TRANSIENT_BACKGROUND; } } else { if (clientProcState < PROCESS_STATE_IMPORTANT_BACKGROUND) { clientProcState = PROCESS_STATE_IMPORTANT_BACKGROUND; } } if (schedGroup < ProcessList.SCHED_GROUP_TOP_APP && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) { schedGroup = ProcessList.SCHED_GROUP_TOP_APP; } if (!trackedProcState) { cr.trackProcState(clientProcState, mAdjSeq, now); } if (procState > clientProcState) { procState = clientProcState; app.setCurRawProcState(procState); if (adjType == null) { adjType = "service"; } } if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND && (cr.flags & Context.BIND_SHOWING_UI) != 0) { app.setPendingUiClean(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.instanceName; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType + ": " + app + ", due to " + cr.binding.client + " adj=" + adj + " procState=" + ProcessList.makeProcStateString(procState)); } } } else { // BIND_WAIVE_PRIORITY == true // BIND_WAIVE_PRIORITY bindings are special when it comes to the // freezer. Processes bound via WPRI are expected to be running, // but they are not promoted in the LRU list to keep them out of // cached. As a result, they can freeze based on oom_adj alone. // Normally, bindToDeath would fire when a cached app would die // in the background, but nothing will fire when a running process // pings a frozen process. Accordingly, any cached app that is // bound by an unfrozen app via a WPRI binding has to remain // unfrozen. if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) { app.shouldNotFreeze = true; } } if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { app.treatLikeActivity = true; } final ActivityServiceConnectionsHolder a = cr.activity; if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && a.isActivityVisible()) { adj = ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(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.setCached(false); app.adjType = "service"; app.adjTypeCode = ActivityManager.RunningAppProcessInfo .REASON_SERVICE_IN_USE; app.adjSource = a; app.adjSourceProcState = procState; app.adjTarget = s.instanceName; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to service w/activity: " + app); } } } } } } for (int provi = app.pubProviders.size() - 1; provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND || procState > 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 > 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; } if (computeClients) { computeOomAdjLocked(client, cachedAdj, topApp, doingAll, now, cycleReEval, true); } else { client.setCurRawAdj(client.setAdj); client.setCurRawProcState(client.setProcState); } if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; } int clientAdj = client.getCurRawAdj(); int clientProcState = client.getCurRawProcState(); if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. clientProcState = PROCESS_STATE_CACHED_EMPTY; } String adjType = null; if (adj > clientAdj) { if (app.hasShownUi && !app.getCachedIsHomeProcess() && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { adjType = "cch-ui-provider"; } else { adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); adjType = "provider"; } app.setCached(app.isCached() & client.isCached()); } if (clientProcState <= PROCESS_STATE_FOREGROUND_SERVICE) { if (adjType == null) { adjType = "provider"; } if (clientProcState == PROCESS_STATE_TOP) { clientProcState = PROCESS_STATE_BOUND_TOP; } else { clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } } conn.trackProcState(clientProcState, mAdjSeq, now); if (procState > clientProcState) { procState = clientProcState; app.setCurRawProcState(procState); } if (client.getCurrentSchedulingGroup() > schedGroup) { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; } if (adjType != null) { app.adjType = adjType; app.adjTypeCode = ActivityManager.RunningAppProcessInfo .REASON_PROVIDER_IN_USE; app.adjSource = client; app.adjSourceProcState = clientProcState; app.adjTarget = cpr.name; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType + ": " + app + ", due to " + client + " adj=" + adj + " procState=" + ProcessList.makeProcStateString(procState)); } } } // If the provider has external (non-framework) process // dependencies, ensure that its adjustment is at least // FOREGROUND_APP_ADJ. if (cpr.hasExternalProcessHandles()) { if (adj > ProcessList.FOREGROUND_APP_ADJ) { adj = ProcessList.FOREGROUND_APP_ADJ; app.setCurRawAdj(adj); schedGroup = ProcessList.SCHED_GROUP_DEFAULT; app.setCached(false); app.adjType = "ext-provider"; app.adjTarget = cpr.name; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to external provider: " + app); } } if (procState > PROCESS_STATE_IMPORTANT_FOREGROUND) { procState = PROCESS_STATE_IMPORTANT_FOREGROUND; app.setCurRawProcState(procState); if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to external provider: " + app); } } } } if (app.lastProviderTime > 0 && (app.lastProviderTime + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) { if (adj > ProcessList.PREVIOUS_APP_ADJ) { adj = ProcessList.PREVIOUS_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; app.setCached(false); app.adjType = "recent-provider"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to recent provider: " + app); } } if (procState > PROCESS_STATE_LAST_ACTIVITY) { procState = PROCESS_STATE_LAST_ACTIVITY; app.adjType = "recent-provider"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to recent provider: " + app); } } } if (procState >= PROCESS_STATE_CACHED_EMPTY) { if (app.hasClientActivities()) { // This is a cached process, but with client activities. Mark it so. procState = 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 = PROCESS_STATE_CACHED_ACTIVITY; app.adjType = "cch-as-act"; } } if (adj == ProcessList.SERVICE_ADJ) { if (doingAll && !cycleReEval) { app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); mNewNumServiceProcs++; //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); if (!app.serviceb) { // This service isn't far enough down on the LRU list to // normally be a B service, but if we are low on RAM and it // is large we want to force it down since we would prefer to // keep launcher over it. if (mService.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.setCurRawAdj(adj); //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); if (adj > app.maxAdj) { adj = app.maxAdj; if (app.maxAdj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; } } // Put bound foreground services in a special sched group for additional // restrictions on screen off if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE && mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) { if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) { schedGroup = ProcessList.SCHED_GROUP_RESTRICTED; } } // apply capability from FGS. if (app.hasForegroundServices()) { capability |= capabilityFromFGS; } capability |= getDefaultCapability(app, procState); // 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); if (app.processName.equals("cn.weipass.service") || app.processName.equals("com.wiseasy.nfcservice") || app.processName.startsWith("cn.wiseasy.leopardclaw") || app.processName.startsWith("com.wangpos.updatespdemo") || app.processName.equals("wangpos.sdk4.base") || app.processName.equals("com.nlscan.scantool") || app.processName.equals("wangpos.sdk4.emv") || app.processName.equals("wangpos.sdk4.keymanager") || app.processName.equals("com.android.externalstorage") || app.processName.equals("com.android.settings.intelligence") || app.processName.equals("android.process.media") || app.processName.equals("com.android.aging") || app.processName.equals("com.wpos.sdkdemo") || app.processName.equals("com.android.settings") || app.processName.equals("com.android.managedprovisioning") || app.processName.equals("com.google.android.apps.work.clouddpc") || app.processName.equals("com.qualcomm.qti.qms.service.connectionsecurity") || app.processName.equals("com.google.android.configupdater") || app.processName.equals("com.google.process.gapps") || app.processName.equals("com.android.vending") || app.processName.equals("com.google.process.gservices") || app.processName.equals("com.google.android.gms.ui")) { app.curAdj = 0; } app.curCapability = capability; app.setCurrentSchedulingGroup(schedGroup); app.setCurProcState(procState); app.setCurRawProcState(procState); app.setHasForegroundActivities(foregroundActivities); app.completedAdjSeq = mAdjSeq; if ("com.idtech.watchdog".equals(app.processName)) { adj = 200; // Target OOM adj value schedGroup = ProcessList.SCHED_GROUP_DEFAULT; procState = ActivityManager.PROCESS_STATE_SERVICE; // Example state, choose appropriately // Skip further adj computations for this process app.curRawAdj = adj; app.curAdj = adj; app.setSchedGroup = schedGroup; //app.setCurProcState(procState); return true; // Or break out of the adjustment logic if possible } // if curAdj or curProcState improved, then this process was promoted return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState || app.curCapability != prevCapability ; } 普通应用com.idtech.watchdog 如何再framework和lmkd 调整 不被容易杀掉
最新发布
08-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值