Android 11.0 关于app进程保活
需求:客户某些重要的app,在后台或者在内存紧张的时候,不允许被杀死
ActivityManagerService
./frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
//清除与该进程的所有连接
final void handleAppDiedLocked(ProcessRecord app,
boolean restarting, boolean allowRestart) {
int pid = app.pid;
boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
false /*replacingPid*/);
if (!kept && !restarting) {
removeLruProcessLocked(app);
if (pid > 0) {
ProcessList.remove(pid);
}
}
if (mProfileData.getProfileProc() == app) {
clearProfilerLocked();
}
mAtmInternal.handleAppDied(app.getWindowProcessController(), restarting, () -> {
Slog.w(TAG, "Crash of app " + app.processName
+ " running instrumentation " + app.getActiveInstrumentation().mClass);
Bundle info = new Bundle();
info.putString("shortMsg", "Process crashed.");
finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
});
}
final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
if (index >= 0) {
removeLruProcessLocked(app);
ProcessList.remove(app.pid);
}
//add text
boolean app_flag = false;
if("com.android.xxx".contains(app.processName)){
app_flag = true;
}
//add text
...
if ( !app_flag && (!app.isPersistent() || app.isolated)) {//进行判断
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
"Removing non-persistent process during cleanup: " + app);
if (!replacingPid) {
mProcessList.removeProcessNameLocked(app.processName, app.uid, app);
}
mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());//清理某个app进程
} else if (!app.removed) {
...
提高某个app的adj,防止系统内存紧张查杀
./frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
@GuardedBy("mService")
private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
ProcessRecord TOP_APP, boolean doingAll, long now) {
if (app.thread == null) {
return false;
}
app.resetCachedInfo();
UidRecord uidRec = app.uidRecord;
if (uidRec != null) {
if (DEBUG_UID_OBSERVERS) {
Slog.i(TAG_UID_OBSERVERS, "Starting update of " + uidRec);
}
uidRec.reset();
}
computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now, false, true);
boolean success = applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
...
ADJ级别
NATIVE_ADJ -1000 native进程
SYSTEM_ADJ -900 仅指system_server进程
PERSISTENT_PROC_ADJ -800 系统persistent进程
PERSISTENT_SERVICE_ADJ -700 关联着系统或persistent进程
FOREGROUND_APP_ADJ 0 前台进程
VISIBLE_APP_ADJ 100 可见进程
PERCEPTIBLE_APP_ADJ 200 可感知进程,比如后台音乐播放
./frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
private boolean isInWhitelist(ProcessRecord pr) {
String packageName = pr.info.packageName;
List<String> whitelist = new ArrayList();
if(whitelist != null && whitelist.size() > 0){
for (String token : whitelist) {
if (packageName.startsWith(token)) {
return true;
}
}
}
return false;
}
private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
long nowElapsed) {
boolean success = true;
if (app.getCurRawAdj() != app.setRawAdj) {
app.setRawAdj = app.getCurRawAdj();
}
...
//add text update
if (app.curAdj != app.setAdj) { //把新的adj更新到lmkd,然后lmkd根据adj等级查杀
/*ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) {
String msg = "Set " + app.pid + " " + app.processName + " adj "
+ app.curAdj + ": " + app.adjType;
reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
}
app.setAdj = app.curAdj;
app.verifiedAdj = ProcessList.INVALID_ADJ;
synchronized (mCachedAppOptimizer) {
app.mSetAdjForCompact = app.setAdj;
}*/
boolean is_white_apps_flag = false;
if (isInWhitelist(app) && (app.curAdj > ProcessList.PERSISTENT_SERVICE_ADJ)) {
is_white_apps_flag = true;
}
if (is_white_apps_flag) {
//是白名单,把adj提升为persistent进程
ProcessList.setOomAdj(app.pid, app.uid, ProcessList.PERSISTENT_SERVICE_ADJ);
if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) {
String msg = "Set " + app.pid + " " + app.processName + " adj "
+ app.curAdj + ": " + app.adjType;
reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
}
app.setAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
app.verifiedAdj = ProcessList.INVALID_ADJ;
} else {
ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) {
String msg = "Set " + app.pid + " " + app.processName + " adj "
+ app.curAdj + ": " + app.adjType;
reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
}
app.setAdj = app.curAdj;
app.verifiedAdj = ProcessList.INVALID_ADJ;
}
synchronized (mCachedAppOptimizer) {
app.mSetAdjForCompact = app.setAdj;
}
}
//add text update
final int curSchedGroup = app.getCurrentSchedulingGroup();
if (app.setSchedGroup != curSchedGroup) {
int oldSchedGroup = app.setSchedGroup;
...
点击Recent时,客户主动清理app后台时,拦截
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents,
String reason) {
final Task task =
mRootWindowContainer.anyTaskForId(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
if (task != null) {
//add text
ComponentName component = task.getBaseIntent().getComponent();
if(component!=null){
String pkg=component.getPackageName();
List<String> list= new ArrayList();
list.add("com.android.sss");
if(list!=null && list.contains(pkg)){
return false;
}
}
//add text
removeTask(task, killProcess, removeFromRecents, reason);
return true;
}
Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
return false;
}
void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason) {
if (task.mInRemoveTask) {
// Prevent recursion.
return;
}
task.mInRemoveTask = true;
try {
task.performClearTask(reason);
cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents);
mService.getLockTaskController().clearLockedTask(task);
mService.getTaskChangeNotificationController().notifyTaskStackChanged();
if (task.isPersistable) {
mService.notifyTaskPersisterLocked(null, true);
}
} finally {
task.mInRemoveTask = false;
}
}
低内存时,禁止某个app被kill掉功能实现(lowmemorykiller)
+++ b/system/memory/lmkd/lmkd.cpp
@@ -2080,6 +2080,15 @@ static int kill_one_process(struct proc* procp, int min_oom_score, enum kill_rea
tgid = proc_get_tgid(pid);
if (tgid >= 0 && tgid != pid) {
ALOGE("Possible pid reuse detected (pid %d, tgid %d)!", pid, tgid);
goto out;
}
taskname = proc_get_name(pid, buf, sizeof(buf));
if (!taskname) {
goto out;
}
+ //add text
+ char packageName[25];
+ strncpy(packageName, taskname, sizeof("com.xx.xx"));//复制
+ ALOGE("packageName=%s,taskname=%s,strcmp=%d",packageName,taskname,strcmp(packageName,"com.android.test"));//比较
+ if(!strcmp(packageName,"com.android.test")){
+ return -1000;
+ }
+ //add text
+
tasksize = proc_get_size(pid);
if (tasksize <= 0) {
goto out;