Android S adj调整 --- computeOomAdjLSP流程详解
Android S adj调整 — computeOomAdjLSP流程详解
这次就先讲OomAdjuster.java中adj调整最为关键的函数computeOomAdjLSP,这个函数几乎占了adj调整代码1/3的代码量,非常重要,建议阅读之前先看一下之前的:Android S进程的adj值 、Android adj调整时的各类进程状态 。至于OomAdjuster.java里面的其它逻辑,下次有时间再来写吧。希望对大家有帮助
1. computeOomAdjLSP的参数
注意此处上了2把锁mService(ActivityManagerService) , ActivityManagerService的mProcLock
@GuardedBy({"mService", "mProcLock"})
private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,
ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
boolean computeClients) {
//调整adj的函数(查看这个函数之前先看一下adj各个值的意思和procState各个值的含义,具体可以参考之前的文章) //1. app是需要调整adj的进程 //2. cachedAdj是adj调整的时候的默认值(除了一些正在使用的app都是这个默认值),默认只有一般是oldAdj或则UNKNOWN_ADJ //3. topApp(当前最顶端activity)是从AMS的getTopApp(这个函数有点性能问题)里面拿到的(这里又是从ActivityTaskManagerService获得) //updateTopResumedActivityIfNeeded/mRootWindowContainer.getTopDisplayFocusedRootTask/topRootTask.getResumedActivity(ActivityTaskSupervisor) //-> updateTopApp(ActivityTaskManagerService),大概是意思是:top的task(writeWmTaskMoved/writeWmTaskToFront),而且是isTopActivityFocusable和可见shouldBeVisible //注意顶端activity和顶端Window不是一个概念,如在桌面的时候下拉状态栏,此时顶端activity(topApp)是桌面,而focus Window是systemui //4. doingAll在这里主要是用于调整A、B service,在updateOomAdjInnerLSP时fullUpdate或者computeClients为true时才有可能设置为true //而A、B service调整除了doingAll这个参数,还跟cycleReEval有关系,也就是说实际有用到的地方只有fullUpdate为true是才会调整A、B services //5. now是此次调整adj的当前时间 //6. cycleReEval只有在设置了setContainsCycle true(如正在计算computeOomAdjLSP的时候还没计算完又跑进来, //如上面的mAdjSeq == state.getAdjSeq()或者(服务/provider的客户端有这种情况的时候)), //在updateOomAdjInnerLSP会让cycleReEval=true(具体可以看上面的updateOomAdjInnerLSP,大概意思是循环计算依赖) //7. computeClients是否需要计算当前进程的时候计算服务、provider提供者对端的adj //8. 它的返回值state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState // || state.getCurCapability() != prevCapability //当满足当前调整的mSetAdj(函数结束的时候)比prevAppAdj(刚进入这里mSetAdj)小的时候,或者mCurProcState有变小;这些都代表优先级提升 //或者mCurCapability能力不一样才返回true,其它都是false. //这个返回值目前只在updateOomAdjInnerLSP中的循环计算adj中使用,用于判断是否需要中断循环调整adj,其它场景都未使用 //只有true才代表循环调整成功,单个进程false代表忽略,只有全部循环调整的进程都是fasle才会跳过循环调整的重试逻辑
2. 是否存在循环计算
设置该进程是循环计算setContainsCycle(true) 、将循环计算的进程进程放入mProcessesInCycle
final ProcessStateRecord state = app.mState;
if (mAdjSeq == state.getAdjSeq()) {
if (state.getAdjSeq() == state.getCompletedAdjSeq()) {
return false;
} else {
state.setContainsCycle(true);
mProcessesInCycle.add(app);
return false;
}
}
3. 没有ApplicationThread的时候的调整
进程app没有ApplicationThread (应用线程)的时候会进入
if (app.getThread() == null) {
state.setAdjSeq(mAdjSeq);
state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND);
state.setCurProcState(PROCESS_STATE_CACHED_EMPTY);
state.setCurAdj(ProcessList.CACHED_APP_MAX_ADJ);
state.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ);
state.setCompletedAdjSeq(state.getAdjSeq());
state.setCurCapability(PROCESS_CAPABILITY_NONE);
return false;
}
4. 对ProcessStateRecord进程状态记录的一些初始化
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN);
state.setAdjSource(null);
state.setAdjTarget(null);
state.setEmpty(false);
state.setCached(false);
state.resetAllowStartFgsState();
5. 设置默认是否允许冻结
//cycleReEval只有在设置了setContainsCycle true(如正在计算computeOomAdjLSP的时候还没计算完又跑进来, //如上面的mAdjSeq == state.getAdjSeq()或者(服务/provider的客户端有这种情况的时候)), //在updateOomAdjInnerLSP会让cycleReEval=true(具体可以看上面的updateOomAdjInnerLSP,大概意思是循环计算依赖)
if (!cycleReEval) {
app.mOptRecord.setShouldNotFreeze(false);
}
6. 获取调整之前的一些状态
final int appUid = app.info.uid;
final int logUid = mService.mCurOomAdjUid;
int prevAppAdj = state.getCurAdj();
int prevProcState = state.getCurProcState();
int prevCapability = state.getCurCapability();
final ProcessServiceRecord psr = app.mServices;
7. system_server或者常驻进程的调整
//getMaxAdj拿到的是mMaxAdj,一般只有系统system_server、常驻进程PERSISTENT或者isolated的app才会设置该值 //而小于等于前台的adj,那么就只有系统system_server、常驻进程PERSISTENT、常驻服务PERSISTENT_SERVICE才会进来 //目前除了测试用例,系统默认的setMaxAdj都是会进来这里的
if (state.getMaxAdj() <= ProcessList.FOREGROUND_APP_ADJ) {
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
}
state.setAdjType("fixed");
state.setAdjSeq(mAdjSeq);
state.setCurRawAdj(state.getMaxAdj());
state.setHasForegroundActivities(false);
state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
state.setCurCapability(PROCESS_CAPABILITY_ALL);
state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
state.setSystemNoUi(true);
if (app == topApp) {
state.setSystemNoUi(false);
state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP);
state.setAdjType("pers-top-activity");
} else if (state.hasTopUi()) {
state.setSystemNoUi(false);
state.setAdjType("pers-top-ui");
} else if (state.getCachedHasVisibleActivities()) {
state.setSystemNoUi(false);
}
if (!state.isSystemNoUi()) {
if (mService.mWakefulness.get() == PowerManagerInternal.WAKEFULNESS_AWAKE
|| state.isRunningRemoteAnimation()) {
state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI);
state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP);
} else {
state.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED);
}
}
state.setCurRawProcState(state.getCurProcState());
state.setCurAdj(state.getMaxAdj());
state.setCompletedAdjSeq(state.getAdjSeq());
state.bumpAllowStartFgsState(state.getCurProcState());
return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState;
}
8. 调整之前的一些变量的定义
state.setSystemNoUi(false);
final int PROCESS_STATE_CUR_TOP = mService.mAtmInternal.getTopProcessState();
int adj;
int schedGroup;
int procState;
int cachedAdjSeq;
int capability = 0;
boolean foregroundActivities = false;
boolean hasVisibleActivities = false;
9. top顶端app的调整
//如果当前是唤醒状态(如亮屏),而且本次调整的进程是topApp(顶端的activity)
if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
state.setAdjType("top-activity");
foregroundActivities = true;
hasVisibleActivities = true;
procState = PROCESS_STATE_CUR_TOP;
state.bumpAllowStartFgsState(PROCESS_STATE_TOP);
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
}
10. 正在播放远端动画的调整
} else if (state.isRunningRemoteAnimation()) {
adj = ProcessList.VISIBLE_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
state.setAdjType("running-remote-anim");
procState = PROCESS_STATE_CUR_TOP;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
}
11. instrumentation的调整
} else if (app.getActiveInstrumentation() != null) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
state.setAdjType("instrumentation");
procState = PROCESS_STATE_FOREGROUND_SERVICE;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
}
12. 正在接受广播进程的调整
//如果正在接受广播(getCurReceiverAt) 或者广播挂起(mPendingBroadcast) 马上会接收时 //可以看到广播adj设置优先于服务adj设置
} else if (state.getCachedIsReceivingBroadcast(mTmpBroadcastQueue)) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = (mTmpBroadcastQueue.contains(mService.mFgBroadcastQueue))
? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
state.setAdjType("broadcast");
procState = ActivityManager.PROCESS_STATE_RECEIVER;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
}
13. 正在运行服务进程的调整
//如果正在运行服务bumpServiceExecutingLocked(startExecutingService加入运行服务,stopExecutingService移除)
} else if (psr.numberOfExecutingServices() > 0) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = psr.shouldExecServicesFg()
? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
state.setAdjType("exec-service");
procState = PROCESS_STATE_SERVICE;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
}
14. 系统在休眠时topApp的调整
//如果调整的是topApp,但是在休眠的时候
} else if (app == topApp) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
state.setAdjType("top-sleeping");
foregroundActivities = true;
procState = PROCESS_STATE_CUR_TOP;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
}
15. 其它app的默认状态初始化
} else {
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
adj = cachedAdj;
procState = PROCESS_STATE_CACHED_EMPTY;
if (!state.containsCycle()) {
state.setCached(true);
state.setEmpty(true);
state.setAdjType("cch-empty");
}
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
}
}
16. 更新foregroundActivities和mHasVisibleActivities
if (!foregroundActivities && state.getCachedHasActivities()) {
state.computeOomAdjFromActivitiesIfNecessary(mTmpComputeOomAdjWindowCallback,
adj, foregroundActivities, hasVisibleActivities, procState, schedGroup,
appUid, logUid, PROCESS_STATE_CUR_TOP);
adj = state.getCachedAdj();
foregroundActivities = state.getCachedForegroundActivities();
hasVisibleActivities = state.getCachedHasVisibleActivities();
procState = state.getCachedProcState();
schedGroup = state.getCachedSchedGroup();
}
17. 更新最近使用的activity的状态
if (procState > PROCESS_STATE_CACHED_RECENT && state.getCachedHasRecentTasks()) {
procState = PROCESS_STATE_CACHED_RECENT;
state.setAdjType("cch-rec");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app);
}
}
18. 调整前台服务或者hasOverlayUi的进程
//如果当前adj大于200(PERCEPTIBLE_APP_ADJ用户可感知的进程) //或者当前进程状态大于PROCESS_STATE_FOREGROUND_SERVICE(前台运行的服务)
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
|| procState > PROCESS_STATE_FOREGROUND_SERVICE) {
if (psr.hasForegroundServices()) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
procState = PROCESS_STATE_FOREGROUND_SERVICE;
state.bumpAllowStartFgsState(PROCESS_STATE_FOREGROUND_SERVICE);
state.setAdjType("fg-service");
state.setCached(false);
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + state.getAdjType() + ": "
+ app + " ");
}
} else if (state.hasOverlayUi()) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
procState = PROCESS_STATE_IMPORTANT_FOREGROUND;
state.setCached(false);
state.setAdjType("has-overlay-ui");
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
}
}
}
19. 调整最近活跃的前台服务进程
if (psr.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
&& (state.getLastTopTime() + mConstants.TOP_TO_FGS_GRACE_DURATION > now
|| state.getSetProcState() <= PROCESS_STATE_TOP)) {
adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
state.setAdjType("fg-service-act");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
}
}
20. 调整强制提升到用户可感知的进程
调整通过setProcessImportant 来提升优先级的应用
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
|| procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
if (state.getForcingToImportant() != null) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
state.setCached(false);
state.setAdjType("force-imp");
state.setAdjSource(state.getForcingToImportant());
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
}
}
}
21. 调整heavy的进程
if (state.getCachedIsHeavyWeight()) {
if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("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;
state.setAdjType("heavy");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app);
}
}
}
21. 调整桌面应用
if (state.getCachedIsHomeProcess()) {
if (adj > ProcessList.HOME_APP_ADJ) {
adj = ProcessList.HOME_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("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;
state.setAdjType("home");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app);
}
}
}
22. 调整previous上一个使用的应用
if (state.getCachedIsPreviousProcess() && state.getCachedHasActivities()) {
if (adj > ProcessList.PREVIOUS_APP_ADJ) {
adj = ProcessList.PREVIOUS_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("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;
state.setAdjType("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=" + state.getAdjType());
23. 循环计算时更新procState、adj、schedGroup
循环计算时更新进程状态procState、进程优先级adj、进程分组cgroup信息schedGroup
if (cycleReEval) {
procState = Math.min(procState, state.getCurRawProcState());
adj = Math.min(adj, state.getCurRawAdj());
schedGroup = Math.max(schedGroup, state.getCurrentSchedulingGroup());
}
24. 先更新一下当前计算的值到ProcessStateRecord
先更新一下当前计算的值到ProcessStateRecord (进程状态信息记录)
state.setCurRawAdj(adj);
state.setCurRawProcState(procState);
state.setHasStartedServices(false);
25. 设置当前adj调整的系列号
state.setAdjSeq(mAdjSeq);
26. 调整backup备份的应用
final BackupRecord backupTarget = mService.mBackupTargets.get(app.userId);
if (backupTarget != null && app == backupTarget.app) {
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;
}
state.setAdjType("backup");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
}
state.setCached(false);
}
if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
procState = ActivityManager.PROCESS_STATE_BACKUP;
state.setAdjType("backup");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app);
}
}
}
27. service服务自身和服务依赖关系调整
27.1 遍历该进程的服务numberOfRunningServices
int capabilityFromFGS = 0;
boolean scheduleLikeTopApp = false;
for (int is = psr.numberOfRunningServices() - 1;
is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
is--) {
ServiceRecord s = psr.getRunningServiceAt(is);
27.2 根据Services自身的状态进行调整
if (s.startRequested) {
state.setHasStartedServices(true);
if (procState > PROCESS_STATE_SERVICE) {
procState = PROCESS_STATE_SERVICE;
state.setAdjType("started-services");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ,
"Raise procstate to started service: " + app);
}
}
if (!s.mKeepWarming && state.hasShownUi() && !state.getCachedIsHomeProcess()) {
if (adj > ProcessList.SERVICE_ADJ) {
state.setAdjType("cch-started-ui-services");
}
} else {
if (s.mKeepWarming
|| now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
if (adj > ProcessList.SERVICE_ADJ) {
adj = ProcessList.SERVICE_ADJ;
state.setAdjType("started-services");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ,
"Raise adj to started service: " + app);
}
state.setCached(false);
}
}
if (adj > ProcessList.SERVICE_ADJ) {
state.setAdjType("cch-started-services");
}
}
}
27.3 获取前台服务的能力capabilityFromFGS
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 = getPlatformCompatCache().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;
}
}
}
27.4 遍历每个服务里面的所有链接对象
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);
27.5 取出每个服务链接对象
for (int i = 0;
i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
i++) {
ConnectionRecord cr = clist.get(i);
27.6 只调整自身是服务,由于客户端的链接的情况
只有服务端的adj,才会由于客户端的adj提升而得到相应的提升
这里就是服务依赖关系调整的开始
if (cr.binding.client == app) {
continue;
}
27.7 computeClients循环计算时,会先计算客户端的adj
boolean trackedProcState = false;
ProcessRecord client = cr.binding.client;
final ProcessStateRecord cstate = client.mState;
if (computeClients) {
computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now,
cycleReEval, true);
} else {
cstate.setCurRawAdj(cstate.getCurAdj());
cstate.setCurRawProcState(cstate.getCurProcState());
}
27.8 调整前获取客户端的clientAdj和clientProcState
获取客户端的clientAdj(客户端的adj) 和clientProcState(客户端的进程状态procState)
int clientAdj = cstate.getCurRawAdj();
int clientProcState = cstate.getCurRawProcState();
final boolean clientIsSystem = clientProcState < PROCESS_STATE_TOP;
if (client.mOptRecord.shouldNotFreeze()) {
app.mOptRecord.setShouldNotFreeze(true);
}
27.9 进行没有豁免优先级情况的调整
if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) {
27.9.1 循环计算的时候是否需要先跳过本次计算
if (shouldSkipDueToCycle(app, cstate, procState, adj, cycleReEval)) {
continue;
}
27.9.2 能力capability初始化
if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
capability |= cstate.getCurCapability();
}
if ((cstate.getCurCapability() & PROCESS_CAPABILITY_NETWORK) != 0) {
if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
if ((cr.flags & Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)
!= 0) {
capability |= PROCESS_CAPABILITY_NETWORK;
}
} else {
capability |= PROCESS_CAPABILITY_NETWORK;
}
}
27.9.3 低于cached activity的进程状态clientProcState约束
if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
clientProcState = PROCESS_STATE_CACHED_EMPTY;
}
27.9.4 如果进程设置了在低内存时托管给系统
如果进程设置了在低内存时托管给系统,就可以减少很多进程依赖关系的调整, 不过目前大部分应用没有使用,而且这里规则也不是很细致
String adjType = null;
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) {
app.mOptRecord.setShouldNotFreeze(true);
}
if (state.hasShownUi() && !state.getCachedIsHomeProcess()) {
if (adj > clientAdj) {
adjType = "cch-bound-ui-services";
}
state.setCached(false);
clientAdj = adj;
clientProcState = procState;
} else {
if (now >= (s.lastActivity
+ mConstants.MAX_SERVICE_INACTIVITY)) {
if (adj > clientAdj) {
adjType = "cch-bound-services";
}
clientAdj = adj;
}
}
}
27.9.5 如果clientAdj大于当前服务的adj,则开始adj依赖关系调整
if (adj > clientAdj) {
if (state.hasShownUi() && !state.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 {
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_ALMOST_PERCEPTIBLE) != 0
&& clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
&& adj >= ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ) {
newAdj = ProcessList.PERCEPTIBLE_MEDIUM_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) {
newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
} else {
newAdj = adj;
}
}
if (!cstate.isCached()) {
state.setCached(false);
}
if (adj > newAdj) {
adj = newAdj;
state.setCurRawAdj(adj);
if (DEBUG_OOM_ADJ_REASON) {
boolean nowActivityTime = (now > (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY));
Slog.d(TAG, "newAdjservice: " + app + ", adj = " + adj + ", client = " + client + ", client.uid = " + client.uid
+", nowActivityTime = " + nowActivityTime + ", state.hasShownUi = " + state.hasShownUi()
+ ", clientProcState =" + clientProcState + ", cr = " + cr);
}
adjType = "service";
}
}
}
27.9.6 clientProcState依赖关系调整
if ((cr.flags & (Context.BIND_NOT_FOREGROUND
| Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
final int curSchedGroup = cstate.getCurrentSchedulingGroup();
if (curSchedGroup > schedGroup) {
if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
schedGroup = curSchedGroup;
} else {
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
}
}
if (clientProcState < PROCESS_STATE_TOP) {
if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) {
clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
state.bumpAllowStartFgsState(
PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
} else if (mService.mWakefulness.get()
== 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) {
clientProcState = PROCESS_STATE_BOUND_TOP;
state.bumpAllowStartFgsState(PROCESS_STATE_BOUND_TOP);
boolean enabled = false;
try {
enabled = getPlatformCompatCache().isChangeEnabled(
PROCESS_CAPABILITY_CHANGE_ID, client.info);
} catch (RemoteException e) {
}
if (enabled) {
if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
capability |= cstate.getCurCapability();
} else {
}
} else {
capability |= cstate.getCurCapability();
}
}
} 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
&& clientIsSystem) {
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
scheduleLikeTopApp = true;
}
if (!trackedProcState) {
cr.trackProcState(clientProcState, mAdjSeq, now);
}
if (procState > clientProcState) {
procState = clientProcState;
state.setCurRawProcState(procState);
if (adjType == null) {
adjType = "service";
}
}
if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND
&& (cr.flags & Context.BIND_SHOWING_UI) != 0) {
app.setPendingUiClean(true);
}
27.9.7 service依赖关系原因的输出
if (adjType != null) {
state.setAdjType(adjType);
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE);
state.setAdjSource(cr.binding.client);
state.setAdjSourceProcState(clientProcState);
state.setAdjTarget(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)+ ", client=" + client
+ ", cr=" + cr);
}
}
27.10 BIND_WAIVE_PRIORITY == true豁免优先级调整
} else {
if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) {
app.mOptRecord.setShouldNotFreeze(true);
}
}
27.11 绑定客户端对象是activity的调整
if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
psr.setTreatLikeActivity(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;
state.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;
}
}
state.setCached(false);
state.setAdjType("service");
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE);
state.setAdjSource(a);
state.setAdjSourceProcState(procState);
state.setAdjTarget(s.instanceName);
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ,
"Raise to service w/activity: " + app);
}
}
}
}
}
}
到这里就结束了服务依赖调整:当前是服务进程,由于客户端进程的adj和进程状态,进行服务进程的adj和进程状态调整
28. provider依赖关系调整
provider依赖关系调整:当前是provider内容提供者进程,由于客户端进程的adj和进程状态,进行provider进程的adj和进程状态调整
28.1 只有当前是provider内容提供者进程才调整
final ProcessProviderRecord ppr = app.mProviders;
for (int provi = ppr.numberOfProviders() - 1;
provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
provi--) {
ContentProviderRecord cpr = ppr.getProviderAt(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;
final ProcessStateRecord cstate = client.mState;
if (client == app) {
continue;
}
28.2 循环计算computeClients和判断是否需要跳过本次计算shouldSkipDueToCycle
if (computeClients) {
computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now, cycleReEval, true);
} else {
cstate.setCurRawAdj(cstate.getCurAdj());
cstate.setCurRawProcState(cstate.getCurProcState());
}
if (shouldSkipDueToCycle(app, cstate, procState, adj, cycleReEval)) {
continue;
}
28.3 调整前客户端的clientAdj、clientProcState的记录
int clientAdj = cstate.getCurRawAdj();
int clientProcState = cstate.getCurRawProcState();
if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
clientProcState = PROCESS_STATE_CACHED_EMPTY;
}
if (client.mOptRecord.shouldNotFreeze()) {
app.mOptRecord.setShouldNotFreeze(true);
}
28.4 clientAdj大于provider的adj才进行adj依赖关系调整
String adjType = null;
if (adj > clientAdj) {
if (state.hasShownUi() && !state.getCachedIsHomeProcess()
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
adjType = "cch-ui-provider";
} else {
adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
state.setCurRawAdj(adj);
adjType = "provider";
}
state.setCached(state.isCached() & cstate.isCached());
}
28.5 clientProcState进程状态依赖调整
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;
state.setCurRawProcState(procState);
}
28.6 客户端分组依赖关系调整
if (cstate.getCurrentSchedulingGroup() > schedGroup) {
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
}
28.7 输出provider调整的原因
if (adjType != null) {
state.setAdjType(adjType);
state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
.REASON_PROVIDER_IN_USE);
state.setAdjSource(client);
state.setAdjSourceProcState(clientProcState);
state.setAdjTarget(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)
+ ", target=" + cpr.name );
}
}
}
28.8 hasExternalProcessHandles的调整
if (cpr.hasExternalProcessHandles()) {
if (adj > ProcessList.FOREGROUND_APP_ADJ) {
adj = ProcessList.FOREGROUND_APP_ADJ;
state.setCurRawAdj(adj);
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
state.setCached(false);
state.setAdjType("ext-provider");
state.setAdjTarget(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;
state.setCurRawProcState(procState);
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ,
"Raise procstate to external provider: " + app);
}
}
}
}
29. recent-provider最近使用的provider调整
if (ppr.getLastProviderTime() > 0
&& (ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
if (adj > ProcessList.PREVIOUS_APP_ADJ) {
adj = ProcessList.PREVIOUS_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("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;
state.setAdjType("recent-provider");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ,
"Raise procstate to recent provider: " + app);
}
}
}
30. 服务相关缓存进程CACHED的调整
if (procState >= PROCESS_STATE_CACHED_EMPTY) {
if (psr.hasClientActivities()) {
procState = PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
state.setAdjType("cch-client-act");
} else if (psr.isTreatedLikeActivity()) {
procState = PROCESS_STATE_CACHED_ACTIVITY;
state.setAdjType("cch-as-act");
}
}
31. A、B service分布调整
if (adj == ProcessList.SERVICE_ADJ) {
if (doingAll && !cycleReEval) {
state.setServiceB(mNewNumAServiceProcs > (mNumServiceProcs / 3);
mNewNumServiceProcs++;
if (!state.isServiceB()) {
if (!mService.mAppProfiler.isLastMemoryLevelNormal()
&& app.mProfile.getLastPss()
>= mProcessList.getCachedRestoreThresholdKb()) {
state.setServiceHighRam(true);
state.setServiceB(true);
} else {
mNewNumAServiceProcs++;
}
} else {
state.setServiceHighRam(false);
}
}
if (state.isServiceB()) {
adj = ProcessList.SERVICE_B_ADJ;
}
}
32. 更新最新的adj到mCurRawAdj中
state.setCurRawAdj(adj);
33. 如果还有未处理完的getMaxAdj进程的调整
if (adj > state.getMaxAdj()) {
adj = state.getMaxAdj();
if (adj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
}
}
34. 非唤醒状态时受限制分组SCHED_GROUP_RESTRICTED调整
if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE
&& mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
&& !scheduleLikeTopApp) {
if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
}
}
35. 更新进程的能力capability
if (psr.hasForegroundServices()) {
capability |= capabilityFromFGS;
}
capability |= getDefaultCapability(psr, procState);
36. 更新最新的状态到ProcessStateRecord,完成本次adj调整
state.setCurAdj(psr.modifyRawOomAdj(adj));
state.setCurCapability(capability);
state.setCurrentSchedulingGroup(schedGroup);
state.setCurProcState(procState);
state.setCurRawProcState(procState);
state.updateLastInvisibleTime(hasVisibleActivities);
state.setHasForegroundActivities(foregroundActivities);
state.setCompletedAdjSeq(mAdjSeq);
37. 本次adj调整的返回值
return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState
|| state.getCurCapability() != prevCapability;
}
38. 其它相关代码
38.1 获取默认的进程能力
private int getDefaultCapability(ProcessServiceRecord psr, int procState) {
switch (procState) {
case PROCESS_STATE_PERSISTENT:
case PROCESS_STATE_PERSISTENT_UI:
case PROCESS_STATE_TOP:
return PROCESS_CAPABILITY_ALL;
case PROCESS_STATE_BOUND_TOP:
return PROCESS_CAPABILITY_NETWORK;
case PROCESS_STATE_FOREGROUND_SERVICE:
if (psr.hasForegroundServices()) {
return PROCESS_CAPABILITY_NETWORK;
} else {
return PROCESS_CAPABILITY_ALL_IMPLICIT | PROCESS_CAPABILITY_NETWORK;
}
case PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
return PROCESS_CAPABILITY_NETWORK;
default:
return PROCESS_CAPABILITY_NONE;
}
}
38.1 shouldSkipDueToCycle是否需要在计算依赖关系时跳过计算
private boolean shouldSkipDueToCycle(ProcessRecord app, ProcessStateRecord client,
int procState, int adj, boolean cycleReEval) {
if (client.containsCycle()) {
app.mState.setContainsCycle(true);
mProcessesInCycle.add(app);
if (client.getCompletedAdjSeq() < mAdjSeq) {
if (cycleReEval) {
if (client.getCurRawProcState() >= procState
&& client.getCurRawAdj() >= adj) {
return true;
}
} else {
return true;
}
}
}
return false;
}
|