Android system实战 — Android R(11) 进程保活白名单

Android system实战 — Android R 进程保活白名单

0. 前言

  最近在Android R上实现一些需求,进行记录一下,关于进程保活的基础知识可以参考Android system — 进程生命周期与ADJ,实际上本质上,就是在提高进程的adj等级,从而达到保活的效果,当然如果你不care原理,也可以直接看下面具体实现。

1. 具体实现

  主要涉及源码路径:

platform/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java

1.1 准备工作

在源码实现之前,我们需要先准备进程白名单,并将其编译至system/etc/app_oom_adj.txt

白名单格式如下:

通用格式:

-序号(整数),包名
其中,序号值越小,则意味着对应的包名进程越受到保护,越难被系统回收内存;

该功能设置后,查看是否生效,可以通过查看进程的adj值来确认:

ps -A | grep “进程名”
cat /proc/进程名对应PID/oom_score_adj

例如:
在这里插入图片描述

1.2 源码实现

platform/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java

1.2.1 源码

/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.am;

import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
import static android.os.Process.SCHED_OTHER;
import static android.os.Process.THREAD_GROUP_BACKGROUND;
import static android.os.Process.THREAD_GROUP_DEFAULT;
import static android.os.Process.THREAD_GROUP_RESTRICTED;
import static android.os.Process.THREAD_GROUP_TOP_APP;
import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.os.Process.setProcessGroup;
import static android.os.Process.setThreadPriority;
import static android.os.Process.setThreadScheduler;

import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
import static com.android.server.am.ActivityManagerService.DISPATCH_OOM_ADJ_OBSERVER_MSG;
import static com.android.server.am.ActivityManagerService.IDLE_UIDS_MSG;
import static com.android.server.am.ActivityManagerService.TAG_BACKUP;
import static com.android.server.am.ActivityManagerService.TAG_LRU;
import static com.android.server.am.ActivityManagerService.TAG_OOM_ADJ;
import static com.android.server.am.ActivityManagerService.TAG_PROCESS_OBSERVERS;
import static com.android.server.am.ActivityManagerService.TAG_PSS;
import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerService.TOP_APP_PRIORITY_BOOST;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;

import android.app.ActivityManager;
import android.app.ApplicationExitInfo;
import android.app.usage.UsageEvents;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ServiceInfo;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.compat.IPlatformCompat;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.wm.ActivityServiceConnectionsHolder;
import com.android.server.wm.WindowProcessController;

import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Vector;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * All of the code required to compute proc states and oom_adj values.
 */
public final class OomAdjuster {
    private static final String TAG = "OomAdjuster";
    static final String OOM_ADJ_REASON_METHOD = "updateOomAdj";
    static final String OOM_ADJ_REASON_NONE = OOM_ADJ_REASON_METHOD + "_meh";
    static final String OOM_ADJ_REASON_ACTIVITY = OOM_ADJ_REASON_METHOD + "_activityChange";
    static final String OOM_ADJ_REASON_FINISH_RECEIVER = OOM_ADJ_REASON_METHOD + "_finishReceiver";
    
    ......
    
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            return true;
        });
        mTmpUidRecords = new ActiveUids(service, false);
        mTmpQueue = new ArrayDeque<ProcessRecord>(mConstants.CUR_MAX_CACHED_PROCESSES << 1);
        mNumSlots = ((ProcessList.CACHED_APP_MAX_ADJ - ProcessList.CACHED_APP_MIN_ADJ + 1) >> 1)
                / ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
        IBinder b = ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
        mPlatformCompat = IPlatformCompat.Stub.asInterface(b);

        //for specific process priority guard
        parseCustomsizedAppOomAdj("/system/etc/app_oom_adj.txt");
    }

    void initSettings() {
        mCachedAppOptimizer.init();
        if (mService.mConstants.KEEP_WARMING_SERVICES.size() > 0) {
            final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
            mService.mContext.registerReceiverForAllUsers(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    synchronized (mService) {
                       
                       ......

    /** Inform the oomadj observer of changes to oomadj. Used by tests. */
    @GuardedBy("mService")
    void reportOomAdjMessageLocked(String tag, String msg) {
        Slog.d(tag, msg);
        if (mService.mCurOomAdjObserver != null) {
            mService.mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
        }
    }

    private class AppOomAdj {
        public int m_nOomAdj;
        public String m_sAppName;
        public AppOomAdj(int adj, String appname) {
            this.m_nOomAdj = adj;
            this.m_sAppName = appname;
        }
    }

    private Vector<AppOomAdj> mVec = null;
    private void parseCustomsizedAppOomAdj(String file) {
        try {
            FileReader fr = new FileReader(file);
            BufferedReader br=new BufferedReader(fr);
            String line = "";
            String[] arrs=null;
            AppOomAdj obj = null;

            if (mVec == null) {
                mVec = new Vector<AppOomAdj>();
            }

            while ((line=br.readLine()) != null) {
                arrs=line.split(",");
                obj = new AppOomAdj(Integer.parseInt(arrs[0]), arrs[1]);
                mVec.add(obj);
            }

            br.close();
            fr.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */
    @GuardedBy("mService")
    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
            long nowElapsed) {
        boolean success = true;

        if (app.getCurRawAdj() != app.setRawAdj) {
            app.setRawAdj = app.getCurRawAdj();
        }

        int changes = 0;
        //Slog.d(TAG, "applyOomAdjLocked pkg: " + app.processName+",pid:"+ app.pid+",uid:"+ app.uid +",curAdj:"+app.curAdj+",setAdj:"+app.setAdj);
        if (mVec != null) {
            int i = 0;
            int oom_score_adj = 0;
            for (;i < mVec.size(); i++) {
                if (app.processName.equals(mVec.get(i).m_sAppName)) {
                    //new curAdj point to  {oom_score_adj}
                    oom_score_adj = mVec.get(i).m_nOomAdj;
                    app.curAdj = oom_score_adj;
                    //Slog.d(TAG, "applyOomAdjLocked pkg:"+app.processName+" mVec app.curAdj:"+app.curAdj);
                }
            }
        }

        // don't compact during bootup
        if (mCachedAppOptimizer.useCompaction() && mService.mBooted) {
            // Cached and prev/home compaction
            if (app.curAdj != app.setAdj) {
                // Perform a minor compaction when a perceptible app becomes the prev/home app
                // Perform a major compaction when any app enters cached
                // reminder: here, setAdj is previous state, curAdj is upcoming state
                if (app.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ &&
                        (app.curAdj == ProcessList.PREVIOUS_APP_ADJ ||
                                
    
    ......
    
}

1.2.2 diff文件

From 4a534042738f6793827ab51089bbdd0977b489ad Mon Sep 17 00:00:00 2001
From: yuefu.zhou <yuefu.zhou@amlogic.com>
Date: Fri, 03 Feb 2023 18:32:13 +0800
Subject: [PATCH] AMS: Support for configuring process priority. [2/2]

PD#IPTV-19626

Problem:
need support configure the process priority.

Solution:
Support for configuring process priority.

Verify:
S928X

Change-Id: If5f82e86f2a33a8cfbdf664d6079a9ad904fc4ac
Signed-off-by: yuefu.zhou <yuefu.zhou@amlogic.com>
---

diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index faa7dce..2d0ce94 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -110,6 +110,12 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Vector;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 
 /**
  * All of the code required to compute proc states and oom_adj values.
@@ -265,6 +271,9 @@
                 / ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
         IBinder b = ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
         mPlatformCompat = IPlatformCompat.Stub.asInterface(b);
+
+        //for specific process priority guard
+        parseCustomsizedAppOomAdj("/system/etc/app_oom_adj.txt");
     }
 
     void initSettings() {
@@ -2144,6 +2153,43 @@
         }
     }
 
+    private class AppOomAdj {
+        public int m_nOomAdj;
+        public String m_sAppName;
+        public AppOomAdj(int adj, String appname) {
+            this.m_nOomAdj = adj;
+            this.m_sAppName = appname;
+        }
+    }
+
+    private Vector<AppOomAdj> mVec = null;
+    private void parseCustomsizedAppOomAdj(String file) {
+        try {
+            FileReader fr = new FileReader(file);
+            BufferedReader br=new BufferedReader(fr);
+            String line = "";
+            String[] arrs=null;
+            AppOomAdj obj = null;
+
+            if (mVec == null) {
+                mVec = new Vector<AppOomAdj>();
+            }
+
+            while ((line=br.readLine()) != null) {
+                arrs=line.split(",");
+                obj = new AppOomAdj(Integer.parseInt(arrs[0]), arrs[1]);
+                mVec.add(obj);
+            }
+
+            br.close();
+            fr.close();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
     /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */
     @GuardedBy("mService")
     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
@@ -2155,6 +2201,19 @@
         }
 
         int changes = 0;
+        //Slog.d(TAG, "applyOomAdjLocked pkg: " + app.processName+",pid:"+ app.pid+",uid:"+ app.uid +",curAdj:"+app.curAdj+",setAdj:"+app.setAdj);
+        if (mVec != null) {
+            int i = 0;
+            int oom_score_adj = 0;
+            for (;i < mVec.size(); i++) {
+                if (app.processName.equals(mVec.get(i).m_sAppName)) {
+                    //new curAdj point to  {oom_score_adj}
+                    oom_score_adj = mVec.get(i).m_nOomAdj;
+                    app.curAdj = oom_score_adj;
+                    //Slog.d(TAG, "applyOomAdjLocked pkg:"+app.processName+" mVec app.curAdj:"+app.curAdj);
+                }
+            }
+        }
 
         // don't compact during bootup
         if (mCachedAppOptimizer.useCompaction() && mService.mBooted) {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ʚ兔子的先森ɞ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值