实战-Android 系统黑白名单

本文介绍了如何在Android系统中实现进程的黑白名单管理,白名单保护常驻应用,黑名单限制内存占用。通过修改IActivityManager和ActivityManagerService接口,开发者可以动态设置oomAdj或根据策略杀掉进程。内容涵盖了内存优化机制,如白名单对CACHED_ACTIVITY和CACHED_ACTIVITY_CLIENT的处理,以及黑名单在Service自启动限制的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

增加系统黑白名单,用于控制进程是否常驻,进程优化等。
1).白名单应用避免被系统杀掉,保持常驻
2).黑名单应用,针对性的进行限制,避免常驻内存,系统内存吃紧时,将其杀掉
开发者可以根据自己的策略进行修改扩展。动态的设置oomAdj 或者 直接进行杀掉。

增加黑白名单接口

frameworks/base / core/java/android/app/IActivityManager.aidl

List<String> getProtectedAppList();
void setProtectedAppList(in List<String> protectedAppList);
List<String> getStoppedAppList();
void setStoppedAppList(in List<String> stopAppList);

frameworks/base/core/java/android/app/ActivityManager.java

public List<String> getProtectedAppList() {
        try {
            return getService().getProtectedAppList();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    public void setProtectedAppList(List<String> protectedAppList) {
        try {
            getService().setProtectedAppList(protectedAppList);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    public List<String> getStoppedAppList() {
        try {
            return getService().getStoppedAppList();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    public void setStoppedAppList(List<String> stopAppList) {
        try {
            getService().setStoppedAppList(stopAppList);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    public void killNativeProcess(int[] pids) {
        try {
            getService().killNativeProcess(pids);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

//Begin memory black & white list
    private List<String> mStopAppList = new ArrayList<String>();
    private List<String> mProtectedAppList = new ArrayList<String>();
    @Override
    public List<String> getProtectedAppList() {
        return mProtectedAppList;
    }
    @Override
    public void setProtectedAppList(List<String> protectedAppList) {
        this.mProtectedAppList = protectedAppList;
    }
    @Override
    public List<String> getStoppedAppList() {
        return mStopAppList;
    }
    @Override
    public void setStoppedAppList(List<String> stopAppList) {
        this.mStopAppList = stopAppList;
    }
    //End memory black & white list

白名单控制

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 //Begin memory optimize
    private boolean isProtectedApp(ProcessRecord app, ProcessRecord TOP_APP) {
		boolean rst = false;
		if(null != app && null != TOP_APP && app.uid == TOP_APP.uid){
			Log.i(TAG, app + "has same uid as top app, we should protect it.");
			return true;
		}
		List<String> protectedApps = getProtectedAppList();
    	Log.i(TAG, "check whether app should stop " + app);
    	Log.i(TAG, "protected list contains " + protectedApps);
		if(null != protectedApps && protectedApps.size() > 0){
			for(String processName : protectedApps){
				if(!TextUtils.isEmpty(processName) 
					&& processName.equals(app.processName)){
					rst = true;
					break;
				}
			}
		}
		String tmp = rst?"is":"is not";
    	Log.i(TAG, "app " + app + tmp +" contained in protected list, we should protect it");
		return rst;
	}
    //End memory optimize
final void updateOomAdjLocked() {
	...
	applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
	switch (app.curProcState) {
       case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
       case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
           mNumCachedHiddenProcs++;
           numCached++;
           if (numCached > cachedProcessLimit && !isProtectedApp(app, TOP_APP)) {//这这里针对白名单		应用进行维护
               killUnneededProcessLocked(app, "cached #" + numCached);
           }
           break;
	
}
黑名单控制

这里主要限制的是,服务被杀后,自启动
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

//Begin memory optimize
 private static final int APP_UID_BEGIN = 10000;
 private boolean shouldStopService(ServiceRecord r){
     boolean rst = false;
     List<String> stoppedApps = mAm.getStoppedAppList();
     Log.i(TAG, "check whether service should stop " + r);
     Log.i(TAG, "stop list contains " + stoppedApps);
     if(null != stoppedApps
             && stoppedApps.size() > 0
             && null != r
             && null != r.app
             && r.app.uid >= 10000
             && null != r.appInfo
             && !TextUtils.isEmpty(r.appInfo.packageName)){
         for(String pkgName : stoppedApps){
             if(!TextUtils.isEmpty(pkgName)
                     && pkgName.equals(r.appInfo.packageName)){
                 rst = true;
                 break;
             }
         }
     }
     String tmp = rst?"is":"is not";
     Log.i(TAG, "service " + r + tmp + " contained in stop list");
     return rst;
 }
 //End memory optimize
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
        boolean inDestroying = mDestroyingServices.contains(r);
        if (r != null) {
            if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
                Log.e(TAG, "service " + r.name.toString() + " started");
                //Begin memory optimize 在这里增加限制
                if(shouldStopService(r)){
                    Log.e(TAG, "service " + r.name.toString() + " should be stopped");
                    res = Service.START_NOT_STICKY;
                }
                //End memory optimize
                // This is a call from a service start...  take care of
                // book-keeping.
                r.callStart = true;
                //上面限制后,进行判断
                switch (res) {
                    case Service.START_STICKY_COMPATIBILITY:
                    case Service.START_STICKY: {
                        // We are done with the associated start arguments.
                        r.findDeliveredStart(startId, true);
                        // Don't stop if killed.
                        r.stopIfKilled = false;
                        break;
                    }
                    case Service.START_NOT_STICKY: {
                        // We are done with the associated start arguments.
                        r.findDeliveredStart(startId, true);
                        if (r.getLastStartId() == startId) {
                            // There is no more work, and this service
                            // doesn't want to hang around if killed.
                            r.stopIfKilled = true;
                        }
                        break;
                    }
                    case Service.START_REDELIVER_INTENT: {
                        
                    }
                    case Service.START_TASK_REMOVED_COMPLETE: {
                      
                    }
                    default:
                }
                if (res == Service.START_STICKY_COMPATIBILITY) {
                    r.callStart = false;
                }
            } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
               
            }
            final long origId = Binder.clearCallingIdentity();
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
            Binder.restoreCallingIdentity(origId);
        } else {
            Slog.w(TAG, "Done executing unknown service from pid "
                    + Binder.getCallingPid());
        }
    }

参考:
Android增加系统白名单
从updateOomAdjLocked看lowmemorykiller之外的Android进程回收机制
Service的自动重启问题

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值