需求
增加系统黑白名单,用于控制进程是否常驻,进程优化等。
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的自动重启问题