SDK - Android6.0
为什么需要 “禁止应用自启动”?
秉承 "物尽极用" - 嵌入式设计理念, 在现在的鱼龙混杂的App环境下, 流氓软件特别多, 这些软件通过接收任意全局广播自启, 常驻后台消耗内存.
为什么需要 “清理后台进程”?
某些应用退出后, 并不会清理自己产生的垃圾, 在后台消耗内存
应用启动的方式
1. 通过各式各样的广播启动, 例如: android.intent.action.BOOT_COMPLETED, 毒瘤代表: <豌豆荚>
2. 通过 Intent 意图启动, 分为 Activity 和 Service 方式启动. 前者为前台应用,后者常驻后台
可以从三个角度入手.
那么根据上面的分析, 关于应用自启动的修改就主要聚焦在 AMS(ActivityManagerService) 上面, 这是一个系统进程. 在这里可以理解成, zygote(孵化器)进程的应用管理者. 协助 zygote 保存应用进程信息
需要修改的文件列表:
// 需要修改的 AMS 文件.
modified: services/core/java/com/android/server/am/ActiveServices.java
modified: services/core/java/com/android/server/am/ActivityManagerService.java
modified: services/core/java/com/android/server/am/ActivityStack.java
modified: services/core/java/com/android/server/am/ActivityStackSupervisor.java
// AMS总代码量超 3w 行, 为了是代码看上去整洁, 模块化, 将自定义逻辑抽出类封装.
new file: services/core/java/com/android/server/am/killer/IdentityManager.java
new file: services/core/java/com/android/server/am/killer/SmartDreamLMKManagerService.java
以下代码未作整理
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 134e1d7..1c98704 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -310,27 +310,38 @@ public final class ActiveServices {
throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
-
+
final boolean callerFg;
- boolean callFromSystem = false;
+ boolean callFromSystem = false;
+ boolean callFromVoiceService = false;
+
if (caller != null) {
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
- if(DEBUG_LOWMEM)Slog.v("Tower", "startService: " + service + " callerApp ="+callerApp
- + " type=" + resolvedType + " args=" + service.getExtras());
+ if(DEBUG_LOWMEM) Slog.v("Tower", "startService: " + service + " callerApp =" +
+ callerApp + " type=" + resolvedType + " args=" + service.getExtras());
+
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when starting service " + service);
}
- if(callerApp.uid == 1000)
- callFromSystem = true;
+
+ /// M: @{
+ if (callerApp.uid == Process.SYSTEM_UID) {
+ callFromSystem = true;
+ }
+
+ if (mAm.verifyIdentity(IdentityManager.IDENTITY_VOICESERVICE, callerApp.processName)) {
+ callFromVoiceService = true;
+ }
+ /// M: @}
+
callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
} else {
callerFg = true;
}
-
-
+
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg);
@@ -359,13 +370,24 @@ public final class ActiveServices {
r.delayedStop = false;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))
- {
- if(callFromSystem)//mark call from system
- r.appInfo.flags |= ApplicationInfo.FLAG_MULTIARCH;
- else
- r.appInfo.flags &= ~ApplicationInfo.FLAG_MULTIARCH;
- }
+
+ /// M: @{
+ if (mAm.isConfigNativeKillMode()) {
+ //mark call from system
+ if (callFromSystem)
+ r.appInfo.flags |= ApplicationInfo.FLAG_MULTIARCH;
+ else
+ r.appInfo.flags &= ~ApplicationInfo.FLAG_MULTIARCH;
+ }
+
+ //mark call from system
+ if (mAm.isConfigSunchipKillMode()) {
+ if (callFromSystem || callFromVoiceService)
+ r.appInfo.flags |= ApplicationInfo.FLAG_MULTIARCH;
+ else
+ r.appInfo.flags &= ~ApplicationInfo.FLAG_MULTIARCH;
+ }
+ /// M: @}
final ServiceMap smap = getServiceMap(r.userId);
boolean addToStarting = false;
@@ -714,8 +736,10 @@ public final class ActiveServices {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
+ " type=" + resolvedType + " conn=" + connection.asBinder()
+ " flags=0x" + Integer.toHexString(flags));
+
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
- boolean callFromSystem = false;
+
+ boolean callFromSystem = false;
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
@@ -723,9 +747,11 @@ public final class ActiveServices {
+ ") when binding service " + service);
}
- if(DEBUG_LOWMEM)Slog.v("Tower", "bindService: " + service +"callerApp = "+callerApp
- + " type=" + resolvedType + " conn=" + connection.asBinder()
- + " flags=0x" + Integer.toHexString(flags));
+ if (DEBUG_LOWMEM)
+ Slog.v("Tower", "bindService: " + service +"callerApp = "+callerApp +
+ " type=" + resolvedType + " conn=" + connection.asBinder() +
+ " flags=0x" + Integer.toHexString(flags));
+
ActivityRecord activity = null;
if (token != null) {
activity = ActivityRecord.isInStackLocked(token);
@@ -755,10 +781,11 @@ public final class ActiveServices {
service = service.cloneFilter();
}
}
- callFromSystem = true;
+
+ callFromSystem = true;
}
- if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+ if ((flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
"BIND_TREAT_LIKE_ACTIVITY");
}
@@ -775,14 +802,14 @@ public final class ActiveServices {
return -1;
}
ServiceRecord s = res.record;
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))
- {
- if(callFromSystem)//mark call from system
- s.appInfo.flags |= ApplicationInfo.FLAG_MULTIARCH;
- else
- s.appInfo.flags &= ~ApplicationInfo.FLAG_MULTIARCH;
- }
-
+
+ if (mAm.isConfigNativeKillMode()) {
+ if (callFromSystem)//mark call from system
+ s.appInfo.flags |= ApplicationInfo.FLAG_MULTIARCH;
+ else
+ s.appInfo.flags &= ~ApplicationInfo.FLAG_MULTIARCH;
+ }
+
final long origId = Binder.clearCallingIdentity();
try {
@@ -1622,7 +1649,7 @@ public final class ActiveServices {
while (r.pendingStarts.size() > 0) {
Exception caughtException = null;
- ServiceRecord.StartItem si;
+ ServiceRecord.StartItem si = null;
try {
si = r.pendingStarts.remove(0);
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
diff --git a/services/core/java/com/android/server/am/ActivityAudioFocusHelper.java b/services/core/java/com/android/server/am/ActivityAudioFocusHelper.java
new file mode 100755
index 0000000..43e1e6b
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActivityAudioFocusHelper.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2020 iFinelio Tower
+ *
+ * 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 java.util.Map;
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+
+import android.util.Log;
+
+import android.content.Context;
+
+import android.media.AudioManager;
+
+import android.util.PropertiesXmlParser;
+
+/**
+ * Pending result information to send back to an activity.
+ */
+final class ActivityAudioFocusHelper {
+ private final static String TAG = "ActivityAudioFocusHelper";
+
+ private int requestforUid = 0;
+ private boolean isAlreadyRequest = false;
+ private AudioManager mAudioManager = null;
+ private AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener= null;
+
+ // Applications that do not have the ability to handle audio focus
+ private List<String> AudioFocusHelperlist = null;
+
+ public ActivityAudioFocusHelper(Context context) {
+ // TODO: if add nowlist, must be in Arrays.asList add it!!!
+ Map<String, List<String>> AudioVolumePolicy = new PropertiesXmlParser("/system/etc/xml/policyVolume.xml",
+ new ArrayList<>(Arrays.asList("audiofocus_list")), PropertiesXmlParser.ATTR_ASSET_PACKAGE).getResult();
+ AudioFocusHelperlist = PropertiesXmlParser.getXmlPolicyList(AudioVolumePolicy, "audiofocus_list",
+ new ArrayList<>(Arrays.asList(
+ "cc.mocn",
+ "com.sinyee.babybus",
+ "cn.kuwo.sing.tv",
+ "com.wxb.huiben",
+ "com.wyt.xq.flash",
+ "com.wyt.zxp.xx")));
+
+ if (AudioFocusHelperlist != null && !AudioFocusHelperlist.isEmpty()) {
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+
+ if (mAudioManager != null) {
+ mAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
+ @Override
+ public void onAudioFocusChange(int i) {
+ Log.w(TAG, "FocusChange i = " + i);
+ }
+ };
+
+ // DEBUG
+ Log.d(TAG, " AudioFocusHelperlist : ");
+ for (String value : AudioFocusHelperlist) {
+ Log.d(TAG, " val = " + value);
+ }
+ Log.d(TAG, " Done.");
+ }
+ }
+ }
+
+ public boolean checkNeedAudioFocusHelp(String name) {
+ if ((AudioFocusHelperlist != null) &&
+ PropertiesXmlParser.checkMatch(AudioFocusHelperlist, name)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean requestAudioFocus(String name) {
+ if (name == null)
+ return false;
+
+ if (!checkNeedAudioFocusHelp(name))
+ return false;
+
+ if (mAudioManager != null) {
+ isAlreadyRequest = true;
+ Log.i(TAG, "help <" + name + "> request AudioFocus.");
+ mAudioManager.requestAudioFocus(mAudioFocusChangeListener,
+ AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public void abandonAudioFocus() {
+ if (isAlreadyRequest && mAudioManager != null) {
+ Log.i(TAG, "abandon AudioFocus.");
+ mAudioManager.abandonAudioFocus(mAudioFocusChangeListener);
+ isAlreadyRequest = false;
+ }
+ }
+
+ public boolean getRequestState() {
+ return isAlreadyRequest;
+ }
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
old mode 100644
new mode 100755
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
old mode 100644
new mode 100755
index 945a7d6..8935cfa
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -260,11 +260,18 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
+import android.util.PropertiesXmlParser;
+import android.util.PropertiesStringParser;
+
+/* Modify by arunboy 20181206 */
+import com.android.server.lights.LightsPolicyManager;
+
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
// File that stores last updated system version and called preboot receivers
static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
+ private static final String DEBUG_LOWMEM_TAG = "Tower";
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
@@ -436,7 +443,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// default actuion automatically. Important for devices without direct input
// devices.
private boolean mShowDialogs = true;
-
+
BroadcastQueue mFgBroadcastQueue;
BroadcastQueue mBgBroadcastQueue;
// Convenient for easy iteration over the queues. Foreground is first
@@ -1222,7 +1229,6 @@ public final class ActivityManagerService extends ActivityManagerNative
String mMemWatchDumpFile;
int mMemWatchDumpPid;
int mMemWatchDumpUid;
-
final long[] mTmpLong = new long[1];
static final class ProcessChangeItem {
@@ -1408,7 +1414,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final ServiceThread mHandlerThread;
final MainHandler mHandler;
final UiHandler mUiHandler;
-
+
final class UiHandler extends Handler {
public UiHandler() {
super(com.android.server.UiThread.get().getLooper(), null, true);
@@ -1444,17 +1450,18 @@ public final class ActivityManagerService extends ActivityManagerNative
}
return;
}
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))
- {
- if((mProcessMap.get(proc.processName) != null)||(mServiceMap.get(proc.processName) != null)){
- if(DEBUG_LOWMEM)Slog.w("Tower", "Skipping crash dialog of " + proc + ": filter");
+
+ if (isConfigNativeKillMode()) {
+ if((mProcessMap.get(proc.processName) != null)||(mServiceMap.get(proc.processName) != null)) {
+ if(DEBUG_LOWMEM)Slog.w(DEBUG_LOWMEM_TAG, "Skipping crash dialog of " + proc + ": filter");
if (res != null) {
- res.set(0);
+ res.set(0);
}
return;
}
- }
- mShowDialogs = "vr".equals(android.os.SystemProperties.get("ro.target.product","unknown")) ? false:mShowDialogs;
+ }
+
+ //mShowDialogs = "vr".equals(android.os.SystemProperties.get("ro.target.product","unknown")) ? false:mShowDialogs;
if (mShowDialogs && !mSleeping && !mShuttingDown) {
Dialog d = new AppErrorDialog(mContext,
ActivityManagerService.this, res, proc);
@@ -2186,7 +2193,73 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
};
+
+ public boolean isConfigNativeKillMode() {
+ if (!SystemProperties.getBoolean("sys.cts_gts.status", false) &&
+ (SystemProperties.getBoolean("ro.config.low_ram", false) || SystemProperties.getBoolean("ro.mem_optimise.enable", false))) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // Modify Tower SmartDream 20190822, Disable Permission Check.
+ private static final boolean isDisableShowDialogs = !(SystemProperties.getBoolean("custom.system.showdialog", false));
+ private static final boolean isDisablePermissionCheck = !(SystemProperties.getBoolean("custom.system.premcheck", false));
+ private boolean isConfigDisablePermissionCheck() {
+ return isDisablePermissionCheck;
+ }
+
+ // Modify Tower 20200519. add system audio focus helper for tmall.
+ private ActivityAudioFocusHelper mAmAudioFocusHelper = null;
+ private ActivityAudioFocusHelper createActivityAudioFocusHelper(Context context) {
+ if (PropertiesStringParser.checkMatch(SystemProperties.get("custom.system.audiofocushelper", "Android"),
+ SystemProperties.get("custom.client.id", "Dummy"))) {
+
+ return new ActivityAudioFocusHelper(context);
+ }
+
+ return null;
+ }
+
+ public boolean requestAudioFocusFromHelper(String name) {
+ if (mAmAudioFocusHelper != null) {
+ return mAmAudioFocusHelper.requestAudioFocus(name);
+ }
+
+ return false;
+ }
+
+ public void abandonAudioFocusFromHelper() {
+ if (mAmAudioFocusHelper != null) {
+ mAmAudioFocusHelper.abandonAudioFocus();
+ }
+ }
+
+ private static final boolean mSmartDreamKillEnable = SystemProperties.getBoolean("ro.config.low_mem", false) ||
+ SystemProperties.getBoolean("custom.smartdream.killmode", false);
+ public static boolean isConfigSmartDreamKillMode() {
+ return mSmartDreamKillEnable;
+ }
+ private SmartDreamLMKManagerService mSmartDreamKiller = null;
+ private SmartDreamLMKManagerService createSmartDreamLMKManagerService(ActivityManagerService ams) {
+ if (isConfigSmartDreamKillMode()) {
+ return new SmartDreamLMKManagerService(ams);
+ }
+
+ return null;
+ }
+
+ public boolean verifyIdentity(int type, String name) {
+ if (mSmartDreamKiller != null) {
+ return mSmartDreamKiller.verifyIdentity(type, name);
+ }
+
+ return false;
+ }
+ // End.
+
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
@@ -2439,88 +2512,113 @@ public final class ActivityManagerService extends ActivityManagerNative
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false")))){
- File configureDir = Environment.getRootDirectory();
- File packageForLowmemFilter = new File(configureDir, "etc/lowmem_package_filter.xml");
- if (packageForLowmemFilter.exists()) {
- try {
- FileInputStream stream = new FileInputStream(packageForLowmemFilter);
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
-
- int type;
- do {
- type = parser.next();
- if (type == XmlPullParser.START_TAG) {
- String tag = parser.getName();
- if ("app".equals(tag)) {
- String pkgName = parser.getAttributeValue(null, "package");
- if(pkgName!=null)
- {
- mProcessMap.put(pkgName,pkgName);
- if(DEBUG_LOWMEM)Slog.d("Tower","--add filter package "+pkgName);
- }
- }
- else if("service".equals(tag))
- {
- String serviceName = parser.getAttributeValue(null, "package");
- if(serviceName!=null)
- {
- mServiceMap.put(serviceName,serviceName);
- if(DEBUG_LOWMEM)Slog.d("Tower","---add filter service "+serviceName);
- }
- }
- else if("game".equals(tag))
- {
- String gameName = parser.getAttributeValue(null, "package");
- if(gameName!=null)
- {
- mGameMap.put(gameName,gameName);
- if(DEBUG_LOWMEM)Slog.d("Tower","---add filter game "+gameName);
- }
- }
- else if("prev".equals(tag))
- {
- String prevName = parser.getAttributeValue(null, "package");
- if(prevName!=null)
- {
- mExcludePrevApp.add(prevName);
- if(DEBUG_LOWMEM)Slog.d("Tower","---add filter prevApp "+prevName);
- }
- }
- else if("next".equals(tag))
- {
- String nextName = parser.getAttributeValue(null, "package");
- if(nextName!=null)
- {
- mExcludeNextApp.add(nextName);
- if(DEBUG_LOWMEM)Slog.d("Tower","---add filter nextApp "+nextName);
- }
- }
- else if("empty".equals(tag))
- {
- String emptyName = parser.getAttributeValue(null, "package");
- if(emptyName!=null)
- {
- mExcludeEmptyApp.add(emptyName);
- if(DEBUG_LOWMEM)Slog.d("Tower","---add filter emptyApp "+emptyName);
- }
- }
- }
- } while (type != XmlPullParser.END_DOCUMENT);
- } catch (NullPointerException e) {
- Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
- } catch (NumberFormatException e) {
- Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
- } catch (XmlPullParserException e) {
- Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
- } catch (IOException e) {
- Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
- } catch (IndexOutOfBoundsException e) {
- Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
- }
- }
- }
+ if (isConfigNativeKillMode()) {
+ File configureDir = Environment.getRootDirectory();
+ File packageForLowmemFilter = new File(configureDir, "etc/lowmem_package_filter.xml");
+ if (packageForLowmemFilter.exists())
+ {
+ try
+ {
+ FileInputStream stream = new FileInputStream(packageForLowmemFilter);
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(stream, null);
+
+ int type;
+ do
+ {
+ type = parser.next();
+ if (type == XmlPullParser.START_TAG)
+ {
+ String tag = parser.getName();
+ if ("app".equals(tag))
+ {
+ String pkgName = parser.getAttributeValue(null, "package");
+ if(pkgName!=null)
+ {
+ mProcessMap.put(pkgName,pkgName);
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","--add filter package "+pkgName);
+ }
+ }
+ else if("service".equals(tag))
+ {
+ String serviceName = parser.getAttributeValue(null, "package");
+ if(serviceName!=null)
+ {
+ mServiceMap.put(serviceName,serviceName);
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","---add filter service "+serviceName);
+ }
+ }
+ else if("game".equals(tag))
+ {
+ String gameName = parser.getAttributeValue(null, "package");
+ if(gameName!=null)
+ {
+ mGameMap.put(gameName,gameName);
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","---add filter game "+gameName);
+ }
+ }
+ else if("prev".equals(tag))
+ {
+ String prevName = parser.getAttributeValue(null, "package");
+ if(prevName!=null)
+ {
+ mExcludePrevApp.add(prevName);
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","---add filter prevApp "+prevName);
+ }
+ }
+ else if("next".equals(tag))
+ {
+ String nextName = parser.getAttributeValue(null, "package");
+ if(nextName!=null)
+ {
+ mExcludeNextApp.add(nextName);
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","---add filter nextApp "+nextName);
+ }
+ }
+ else if("empty".equals(tag))
+ {
+ String emptyName = parser.getAttributeValue(null, "package");
+ if(emptyName!=null)
+ {
+ mExcludeEmptyApp.add(emptyName);
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","---add filter emptyApp "+emptyName);
+ }
+ }
+ }
+ }
+ while (type != XmlPullParser.END_DOCUMENT);
+ }
+ catch (NullPointerException e)
+ {
+ Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
+ }
+ catch (NumberFormatException e)
+ {
+ Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
+ }
+ catch (XmlPullParserException e)
+ {
+ Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
+ }
+ catch (IOException e)
+ {
+ Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ Slog.w(TAG, "failed parsing " + packageForLowmemFilter, e);
+ }
+ }
+ }
+
+ mSmartDreamKiller = createSmartDreamLMKManagerService(this);
+ mAmAudioFocusHelper = createActivityAudioFocusHelper(mContext);
}
public void setSystemServiceManager(SystemServiceManager mgr) {
@@ -2780,12 +2878,14 @@ public final class ActivityManagerService extends ActivityManagerNative
finishVoiceTask(last.task.voiceSession);
}
}
- //when user start home launcher,cleanup the complex app.
+
+ //when user start home launcher,cleanup the complex app.
if(last != null && r != null && r.task != null &&
- r.task.taskType == ActivityRecord.HOME_ACTIVITY_TYPE && mGameMap.get(last.processName) != null){
- killBackgroundProcesses(last.packageName,last.userId,"low-mem");
- if(DEBUG_LOWMEM)Slog.v("lly", "----clean memory for stop " + last.processName);
- }
+ r.task.taskType == ActivityRecord.HOME_ACTIVITY_TYPE && mGameMap.get(last.processName) != null) {
+ killBackgroundProcesses(last.packageName, last.userId, "low-mem");
+ if(DEBUG_LOWMEM)Slog.v(DEBUG_LOWMEM_TAG, "----clean memory for stop " + last.processName);
+ }
+
if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
mWindowManager.setFocusedApp(r.appToken, true);
}
@@ -2797,6 +2897,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mLastFocusedUserId = mFocusedActivity.userId;
}
}
+
EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
mFocusedActivity == null ? -1 : mFocusedActivity.userId,
mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
@@ -3126,6 +3227,10 @@ public final class ActivityManagerService extends ActivityManagerNative
"provider reference", cpr, app);
}
}
+
+ if (mSmartDreamKiller != null) {
+ mSmartDreamKiller.addSmartDreamOomAdjLocked(app);
+ }
}
final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
@@ -3260,49 +3365,55 @@ public final class ActivityManagerService extends ActivityManagerNative
// If this is an isolated process, it can't re-use an existing process.
app = null;
}
- if(DEBUG_LOWMEM)Slog.v("Tower", "startProcess: name=" + processName
- + " app=" + app + " knownToBeDead=" + knownToBeDead+" hostingType="+hostingType+" intentFlags="+intentFlags
- + " thread=" + (app != null ? app.thread : null)
- + " pid=" + (app != null ? app.pid : -1));
-
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false")))){
- //if((mProcessMap.get(processName) != null) && ("broadcast".equals(hostingType))){
- final ActivityRecord next = getFocusedStack().topRunningActivityLocked(null);
- if(next!= null && (!next.packageName.equals(processName)&& !processName.contains("antutu")) && next.packageName.contains("antutu")){
- if(DEBUG_LOWMEM)Slog.v("Tower", "process dont start because for antutu: " + next.packageName + "/" + info.processName);
- return null;
- }
-
- if((mProcessMap.get(processName) != null) && (("broadcast".equals(hostingType))||("content provider".equals(hostingType)))){
- if(DEBUG_LOWMEM)Slog.v("Tower", "process dont start because for filter: " + info.uid + "/" + info.processName);
+
+ if (DEBUG_LOWMEM) {
+ Slog.v(DEBUG_LOWMEM_TAG, "startProcess: name=" + processName +
+ " app=" + app + " knownToBeDead=" + knownToBeDead +
+ " hostingType=" + hostingType + " intentFlags=" + intentFlags +
+ " info.flags=" + info.flags +
+ " thread=" + (app != null ? app.thread : null) +
+ " pid=" + (app != null ? app.pid : -1));
+ }
+
+ if (mSmartDreamKiller != null) {
+ if (mSmartDreamKiller.filterMatrix(processName, info, hostingType))
+ return null;
+ }
+
+ if (isConfigNativeKillMode()) {
+ //if((mProcessMap.get(processName) != null) && ("broadcast".equals(hostingType))) {
+ final ActivityRecord next = getFocusedStack().topRunningActivityLocked(null);
+
+ if ((next != null) &&
+ (next.packageName.contains("antutu")) &&
+ (!next.packageName.equals(processName) && !processName.contains("antutu"))) {
+ if(DEBUG_LOWMEM) Slog.v(DEBUG_LOWMEM_TAG, "process dont start because for antutu: " + next.packageName + "/" + info.processName);
+ return null;
+ }
+
+ if ((mProcessMap.get(processName) != null) && (("broadcast".equals(hostingType)) || ("content provider".equals(hostingType)))) {
+ if(DEBUG_LOWMEM) Slog.v(DEBUG_LOWMEM_TAG, "process dont start because for filter: " + info.uid + "/" + info.processName);
return null;
}
- if((mServiceMap.get(processName) != null)&&("service".equals(hostingType))&&((info.flags & ApplicationInfo.FLAG_MULTIARCH) !=0))//for service start by system
- {
- if(DEBUG_LOWMEM)Slog.v("Tower", "service dont start auto because for filter: " + info.uid + "/" + info.processName);
+ // for service start by system
+ if ((mServiceMap.get(processName) != null) && ("service".equals(hostingType)) && ((info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0)) {
+ if(DEBUG_LOWMEM) Slog.v(DEBUG_LOWMEM_TAG, "service dont start auto because for filter: " + info.uid + "/" + info.processName);
return null;
}
- if(((info.flags & ApplicationInfo.FLAG_SYSTEM) ==0)&&("broadcast".equals(hostingType)))
- {
- if(DEBUG_LOWMEM)Slog.v("Tower", "third part process dont start for broadcast: " + info.uid + "/" + info.processName);
- return null;
- }
- if(mGameMap.get(processName) != null)
- {
+ if (mGameMap.get(processName) != null) {
killAllBackgroundProcesses();
- if(DEBUG_LOWMEM)Slog.v("Tower", "----clean memory for start " + info.processName);
+ if(DEBUG_LOWMEM)Slog.v(DEBUG_LOWMEM_TAG, "----clean memory for start " + info.processName);
+ }
+ }
+
+ if (("com.google.android.setupwizard".equals(processName))) {
+ if (isConfigNativeKillMode()) {
+ Log.d(DEBUG_LOWMEM_TAG,"--start com.google.android.setupwizard---");
+ SystemProperties.set("sys.cts_gts.status","true");
}
}
- if(("com.google.android.setupwizard".equals(processName)) && (("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))))
- {
- if(!"true".equals(SystemProperties.get("sys.cts_gts.status", "false")))
- {
- Log.d("Tower","--start com.google.android.setupwizard---");
- SystemProperties.set("sys.cts_gts.status","true");
- }
- }
// app launch boost for big.little configurations
// use cpusets to migrate freshly launched tasks to big cores
@@ -3739,19 +3850,23 @@ public final class ActivityManagerService extends ActivityManagerNative
}
void enforceNotIsolatedCaller(String caller) {
- if (UserHandle.isIsolated(Binder.getCallingUid())) {
- throw new SecurityException("Isolated process not allowed to call " + caller);
- }
+ if (!isConfigDisablePermissionCheck()) {
+ if (UserHandle.isIsolated(Binder.getCallingUid())) {
+ throw new SecurityException("Isolated process not allowed to call " + caller);
+ }
+ }
}
void enforceShellRestriction(String restriction, int userHandle) {
- if (Binder.getCallingUid() == Process.SHELL_UID) {
- if (userHandle < 0
- || mUserManager.hasUserRestriction(restriction, userHandle)) {
- throw new SecurityException("Shell does not have permission to access user "
- + userHandle);
- }
- }
+ if (!isConfigDisablePermissionCheck()) {
+ if (Binder.getCallingUid() == Process.SHELL_UID) {
+ if (userHandle < 0 ||
+ mUserManager.hasUserRestriction(restriction, userHandle)) {
+ throw new SecurityException("Shell does not have permission to access user "
+ + userHandle);
+ }
+ }
+ }
}
@Override
@@ -4461,6 +4576,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mStackSupervisor.showLockTaskToast();
return false;
}
+
if (mController != null) {
// Find the first activity that is not finishing.
ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
@@ -4874,15 +4990,27 @@ public final class ActivityManagerService extends ActivityManagerNative
mAllowLowerMemLevel = false;
doLowMem = false;
}
+
EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
if (DEBUG_CLEANUP) Slog.v(
TAG, "Dying app: " + app + ", pid: " + pid
+ ", thread: " + thread.asBinder());
- boolean isrestart = true;
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))
- if(!"com.android.systemui".equals(app.processName))
- isrestart = false;
- handleAppDiedLocked(app, false, isrestart);
+
+ boolean isAllowRestart = true;
+ if (isConfigNativeKillMode()) {
+ if (!"com.android.systemui".equals(app.processName) ||
+ !"com.android.systemui2".equals(app.processName)) {
+ isAllowRestart = false;
+ }
+ } /// M: SmartDream OOM Policy: reject app reset. @{
+ /*
+ else if (mSmartDreamKiller != null &&
+ mSmartDreamKiller.filterSmartDreamAllowResetProcess(app.processName)) {
+ isAllowRestart = false;
+ }
+ /// M: @}
+ */
+ handleAppDiedLocked(app, false, isAllowRestart);
if (doOomAdj) {
updateOomAdjLocked();
@@ -5314,7 +5442,8 @@ public final class ActivityManagerService extends ActivityManagerNative
android.Manifest.permission.CLEAR_APP_USER_DATA,
pid, uid, -1, true)
== PackageManager.PERMISSION_GRANTED) {
- forceStopPackageLocked(packageName, pkgUid, "clear data");
+ // Modify yl 20190222, for systemui2 clear package cache data.
+ //forceStopPackageLocked(packageName, pkgUid, "clear data");
} else {
throw new SecurityException("PID " + pid + " does not have permission "
+ android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
@@ -5402,7 +5531,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
-
+
long callingId = Binder.clearCallingIdentity();
try {
synchronized(this) {
@@ -5425,11 +5554,12 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
-
- int N = procs.size();
- for (int i=0; i<N; i++) {
- removeProcessLocked(procs.get(i), false, true, "kill all background");
- }
+
+ int N = procs.size();
+ for (int i = 0; i < N; i++) {
+ removeProcessLocked(procs.get(i), false, true, "kill all background");
+ }
+
mAllowLowerMemLevel = true;
updateOomAdjLocked();
doLowMemReportIfNeededLocked(null);
@@ -5439,7 +5569,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- public void killBackgroundProcesses(final String packageName,int userId,String reason) {
+ public void killBackgroundProcesses(final String packageName,int userId, String reason) {
if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
!= PackageManager.PERMISSION_GRANTED &&
checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
@@ -5452,7 +5582,7 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException(msg);
}
- userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
long callingId = Binder.clearCallingIdentity();
try {
@@ -5742,55 +5872,55 @@ public final class ActivityManagerService extends ActivityManagerNative
SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
final int NA = apps.size();
for (int ia=0; ia<NA; ia++) {
- ProcessRecord app = apps.valueAt(ia);
- if (app.persistent && !evenPersistent) {
- // we don't kill persistent processes
- continue;
- }
- if (app.removed) {
- if (doit) {
- procs.add(app);
- }
- continue;
- }
+ ProcessRecord app = apps.valueAt(ia);
+ if (app.persistent && !evenPersistent) {
+ // we don't kill persistent processes
+ continue;
+ }
+ if (app.removed) {
+ if (doit) {
+ procs.add(app);
+ }
+ continue;
+ }
- // Skip process if it doesn't meet our oom adj requirement.
- if (app.setAdj < minOomAdj) {
- continue;
- }
+ // Skip process if it doesn't meet our oom adj requirement.
+ if (app.setAdj < minOomAdj) {
+ continue;
+ }
- // If no package is specified, we call all processes under the
- // give user id.
- if (packageName == null) {
- if (userId != UserHandle.USER_ALL && app.userId != userId) {
- continue;
- }
- if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
- continue;
- }
- // Package has been specified, we want to hit all processes
- // that match it. We need to qualify this by the processes
- // that are running under the specified app and user ID.
- } else {
- final boolean isDep = app.pkgDeps != null
- && app.pkgDeps.contains(packageName);
- if (!isDep && UserHandle.getAppId(app.uid) != appId) {
- continue;
- }
- if (userId != UserHandle.USER_ALL && app.userId != userId) {
- continue;
- }
- if (!app.pkgList.containsKey(packageName) && !isDep) {
- continue;
- }
- }
+ // If no package is specified, we call all processes under the
+ // give user id.
+ if (packageName == null) {
+ if (userId != UserHandle.USER_ALL && app.userId != userId) {
+ continue;
+ }
+ if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
+ continue;
+ }
+ // Package has been specified, we want to hit all processes
+ // that match it. We need to qualify this by the processes
+ // that are running under the specified app and user ID.
+ } else {
+ final boolean isDep = app.pkgDeps != null
+ && app.pkgDeps.contains(packageName);
+ if (!isDep && UserHandle.getAppId(app.uid) != appId) {
+ continue;
+ }
+ if (userId != UserHandle.USER_ALL && app.userId != userId) {
+ continue;
+ }
+ if (!app.pkgList.containsKey(packageName) && !isDep) {
+ continue;
+ }
+ }
- // Process has passed all conditions, kill it!
- if (!doit) {
- return true;
- }
- app.removed = true;
- procs.add(app);
+ // Process has passed all conditions, kill it!
+ if (!doit) {
+ return true;
+ }
+ app.removed = true;
+ procs.add(app);
}
}
@@ -6104,12 +6234,12 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- private final boolean removeProcessLocked(ProcessRecord app,
+ public final boolean removeProcessLocked(ProcessRecord app,
boolean callerWillRestart, boolean allowRestart, String reason) {
final String name = app.processName;
final int uid = app.uid;
if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
- "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
+ "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")" + "reson" + reason);
removeProcessNameLocked(name, uid);
if (mHeavyWeightProcess == app) {
@@ -6814,6 +6944,38 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ /*
+ * The Function supply PMS multrunnable scan package callback.
+ */
+ @Override
+ public void startHomeActivity() {
+ mBooting = true;
+ startHomeActivityLocked(mCurrentUserId, "systemReady");
+
+ if (mBatteryStatsService.isCharging()) {
+ Slog.d(TAG, "detected charging behavior!.");
+ startChargerActivity();
+ }
+
+ LightsPolicyManager.getInstance().startLightsBroadcastReceiver();
+ Slog.d(TAG, "start LightsBroadcastReceiver.");
+ }
+
+ /*
+ * The Function supply SmartDream Custom Application get Top PackageName.
+ */
+ @Override
+ public String getTopActivityInformation() {
+ return mFocusedActivity != null ? mFocusedActivity.packageName : null;
+ }
+
+ @Override
+ public void updateSmartDreamOomAdjLocked() {
+ if (mSmartDreamKiller != null) {
+ mSmartDreamKiller.updateSmartDreamOomAdjLocked();
+ }
+ }
+
@Override
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
@@ -7279,9 +7441,14 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
int checkComponentPermission(String permission, int pid, int uid,
int owningUid, boolean exported) {
- if (pid == MY_PID) {
+ if (isConfigDisablePermissionCheck()) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
+
+ if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
}
+
return ActivityManager.checkComponentPermission(permission, uid,
owningUid, exported);
}
@@ -7297,10 +7464,14 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
@Override
public int checkPermission(String permission, int pid, int uid) {
- if (permission == null) {
- return PackageManager.PERMISSION_DENIED;
- }
- return checkComponentPermission(permission, pid, uid, -1, true);
+ if (isConfigDisablePermissionCheck()) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
+
+ if (permission == null) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+ return checkComponentPermission(permission, pid, uid, -1, true);
}
@Override
@@ -7495,6 +7666,10 @@ public final class ActivityManagerService extends ActivityManagerNative
final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
: UriPermission.STRENGTH_OWNED;
+ if (isConfigDisablePermissionCheck()) {
+ return true;
+ }
+
// Root gets to do everything.
if (uid == 0) {
return true;
@@ -7529,6 +7704,10 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public int checkUriPermission(Uri uri, int pid, int uid,
final int modeFlags, int userId, IBinder callerToken) {
+ if (isConfigDisablePermissionCheck()) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
+
enforceNotIsolatedCaller("checkUriPermission");
// Another redirected-binder-call permissions check as in
@@ -9275,11 +9454,12 @@ public final class ActivityManagerService extends ActivityManagerNative
if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
// startLockTask() called by app and task mode is lockTaskModeDefault.
if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
- StatusBarManagerInternal statusBarManager =
- LocalServices.getService(StatusBarManagerInternal.class);
+
+ StatusBarManagerInternal statusBarManager = LocalServices.getService(StatusBarManagerInternal.class);
if (statusBarManager != null) {
statusBarManager.showScreenPinningRequest();
}
+
return;
}
@@ -10412,6 +10592,14 @@ public final class ActivityManagerService extends ActivityManagerNative
&& (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
r.persistent = true;
}
+
+ if (verifyIdentity(IdentityManager.IDENTITY_SYSTEM, info.processName) ||
+ verifyIdentity(IdentityManager.IDENTITY_LAUNCHER, info.processName) ||
+ verifyIdentity(IdentityManager.IDENTITY_PRIVILEGE, info.processName) ||
+ verifyIdentity(IdentityManager.IDENTITY_VOICESERVICE, info.processName)) {
+ r.persistent = true;
+ Slog.e(TAG, "allow persistent : " + info.processName);
+ }
addProcessNameLocked(r);
return r;
}
@@ -10441,20 +10629,22 @@ public final class ActivityManagerService extends ActivityManagerNative
+ info.packageName + ": " + e);
}
- if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
- == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false")))){
- if((info.processName.contains("com.android.systemui"))||(info.processName.contains("android.process.media")))
- {
- app.persistent = true;
- app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
- if(DEBUG_LOWMEM)Slog.d("Tower","---only set systemui and android.process.media to persist in lowmem devices---");
- }
- }else{
- app.persistent = true;
- app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
- }
- }
+ if ((info.flags & (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
+ == (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT)) {
+ if (isConfigNativeKillMode()) {
+ if((info.processName.contains("com.android.systemui")) ||
+ (info.processName.contains("com.android.systemui2")) ||
+ (info.processName.contains("android.process.media"))) {
+ app.persistent = true;
+ app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
+ if(DEBUG_LOWMEM) Slog.d(DEBUG_LOWMEM_TAG,"---only set systemui and android.process.media to persist in lowmem devices---");
+ }
+ } else {
+ app.persistent = true;
+ app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
+ }
+ }
+
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
startProcessLocked(app, "added application", app.processName, abiOverride,
@@ -11917,6 +12107,18 @@ public final class ActivityManagerService extends ActivityManagerNative
return true;
}
+ private void startChargerActivity() {
+ try {
+ ComponentName mComponent = new ComponentName("com.cx.changer", "com.cx.changer.MainActivity");
+ Intent intent= new Intent(Intent.ACTION_VIEW);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setComponent(mComponent);
+ mContext.startActivity(intent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) {
@@ -12060,16 +12262,18 @@ public final class ActivityManagerService extends ActivityManagerNative
if (apps != null) {
int N = apps.size();
int i;
- for (i=0; i<N; i++) {
- ApplicationInfo info
- = (ApplicationInfo)apps.get(i);
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))
- {
- if((mProcessMap.get(info.processName) != null)||(mServiceMap.get(info.processName) != null)){
- if(DEBUG_LOWMEM)Slog.d("Tower","---low mem mode,system ready skip start persist app= "+info);
- continue;
- }
- }
+ for (i = 0; i < N; i++) {
+ ApplicationInfo info = (ApplicationInfo)apps.get(i);
+ if (isConfigNativeKillMode()) {
+ if((mProcessMap.get(info.processName) != null) || (mServiceMap.get(info.processName) != null)) {
+ if(DEBUG_LOWMEM) {
+ Slog.d(DEBUG_LOWMEM_TAG,"---low mem mode,system ready skip start persist app= " + info);
+ }
+
+ continue;
+ }
+ }
+
if (info != null &&
!info.packageName.equals("android")) {
addAppLocked(info, false, null /* ABI override */);
@@ -12080,10 +12284,10 @@ public final class ActivityManagerService extends ActivityManagerNative
// pm is in same process, this will never happen.
}
}
-
// Start up initial activity.
- mBooting = true;
- startHomeActivityLocked(mCurrentUserId, "systemReady");
+ if (!SystemProperties.getBoolean("custom.system.optimize", false)) {
+ startHomeActivity();
+ }
try {
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
@@ -12832,14 +13036,13 @@ public final class ActivityManagerService extends ActivityManagerNative
return;
}
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))
- {
- if((mProcessMap.get(r.processName) != null)||(mServiceMap.get(r.processName) != null)){
- if(DEBUG_LOWMEM)Slog.d("Tower","-----hide error msg for filter process "+r);
+ if (isConfigNativeKillMode()) {
+ if((mProcessMap.get(r.processName) != null) || (mServiceMap.get(r.processName) != null)) {
+ if(DEBUG_LOWMEM) Slog.d(DEBUG_LOWMEM_TAG,"-----hide error msg for filter process " + r);
Binder.restoreCallingIdentity(origId);
return;
}
- }
+ }
Message msg = Message.obtain();
msg.what = SHOW_ERROR_MSG;
HashMap data = new HashMap();
@@ -13144,6 +13347,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(" write: write all pending state to storage");
pw.println(" track-associations: enable association tracking");
pw.println(" untrack-associations: disable and clear association tracking");
+ pw.println(" smartdream: [set] [debug killer fliter] [boolean]");
pw.println(" cmd may also be a COMP_SPEC to dump activities.");
pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
pw.println(" a partial substring in a component name, a");
@@ -13312,13 +13516,23 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
return;
- } else {
+ } else if ("smartdream".equals(cmd)) {
+ if (mSmartDreamKiller == null) {
+ pw.println("please enable custom.smartdream.killmode");
+ return;
+ }
+
+ mSmartDreamKiller.dumpSmartDreamOOM(pw, args);
+ } else if ("killall".equals(cmd)) {
+ killAllBackgroundProcesses();
+ } else {
// Dumping a single activity?
if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
pw.println("Bad activity command, or no activities match: " + cmd);
pw.println("Use -h for help.");
}
}
+
if (!more) {
Binder.restoreCallingIdentity(origId);
return;
@@ -15768,7 +15982,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
// We left the provider in the launching list, need to
// restart it.
- restart = true;
+ restart = true;
}
cpr.provider = null;
@@ -15873,17 +16087,27 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app == mPreviousProcess) {
mPreviousProcess = null;
}
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false"))))
- && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))//if lowmem config
- {
- if((!"com.android.systemui".equals(app.processName))&&(!"android.process.media".equals(app.processName)))
- {
- if(DEBUG_LOWMEM)Slog.d("Tower","---low mem mode,skip restart crashed app= "+app);
- restart = false;
- }
+
+ /*
+ if (mSmartDreamKiller != null &&
+ mSmartDreamKiller.filterSmartDreamAllowResetProcess(app.processName)) {
+ restart = false;
+ }
+ */
+
+ //if lowmem config
+ if (isConfigNativeKillMode()) {
+ if ((!"com.android.systemui".equals(app.processName)) &&
+ (!"com.android.systemui2".equals(app.processName)) &&
+ (!"android.process.media".equals(app.processName))) {
+ if (DEBUG_LOWMEM)
+ Slog.d(DEBUG_LOWMEM_TAG,"---low mem mode, skip restart crashed app=" + app);
+
+ restart = false;
+ }
}
- if (restart && !app.isolated) {
+ if (restart && !app.isolated) {
// We have components that still need to be running in the
// process, so re-launch it.
if (index < 0) {
@@ -17046,8 +17270,7 @@ public final class ActivityManagerService extends ActivityManagerNative
List receivers = null;
List<BroadcastFilter> registeredReceivers = null;
// Need to resolve the intent to interested receivers...
- if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
- == 0) {
+ if ((intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
if (intent.getComponent() == null) {
@@ -17723,6 +17946,10 @@ public final class ActivityManagerService extends ActivityManagerNative
* dialog / global actions also might want different behaviors.
*/
private static final boolean shouldShowDialogs(Configuration config) {
+ if (isDisableShowDialogs) {
+ return false;
+ }
+
return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
&& config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
&& config.navigation == Configuration.NAVIGATION_NONAV);
@@ -19220,7 +19447,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- private final ActivityRecord resumedAppLocked() {
+ public final ActivityRecord resumedAppLocked() {
ActivityRecord act = mStackSupervisor.resumedAppLocked();
String pkg;
int uid;
@@ -19263,6 +19490,7 @@ public final class ActivityManagerService extends ActivityManagerNative
? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
SystemClock.uptimeMillis());
+
if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
// Changed to/from cached state, so apps after it in the LRU
// list may also be changed.
@@ -19308,10 +19536,10 @@ public final class ActivityManagerService extends ActivityManagerNative
emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
cachedProcessLimit = mProcessLimit - emptyProcessLimit;
}
- if((("true".equals(SystemProperties.get("ro.config.low_ram", "false")))||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))
- {
- emptyProcessLimit = cachedProcessLimit = 0;
- }
+
+ if (isConfigNativeKillMode()) {
+ emptyProcessLimit = cachedProcessLimit = 0;
+ }
// Let's determine how many processes we have running vs.
// how many slots we have for background processes; we may want
@@ -19329,10 +19557,14 @@ public final class ActivityManagerService extends ActivityManagerNative
// instead of a gazillion empty processes.
numEmptyProcs = cachedProcessLimit;
}
- int emptyFactor = numEmptyProcs/numSlots;
- if (emptyFactor < 1) emptyFactor = 1;
- int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
- if (cachedFactor < 1) cachedFactor = 1;
+ int emptyFactor = numEmptyProcs / numSlots;
+ if (emptyFactor < 1)
+ emptyFactor = 1;
+
+ int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1) / numSlots;
+ if (cachedFactor < 1)
+ cachedFactor = 1;
+
int stepCached = 0;
int stepEmpty = 0;
int numCached = 0;
@@ -19348,7 +19580,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int nextCachedAdj = curCachedAdj+1;
int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextEmptyAdj = curEmptyAdj+2;
- for (int i=N-1; i>=0; i--) {
+ for (int i = N-1; i >= 0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (!app.killedByAm && app.thread != null) {
app.procStateChanged = false;
@@ -19409,59 +19641,69 @@ public final class ActivityManagerService extends ActivityManagerNative
applyOomAdjLocked(app, true, now, nowElapsed);
// Count the number of process types.
- switch (app.curProcState) {
- case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
- case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
- mNumCachedHiddenProcs++;
- numCached++;
- if (numCached > cachedProcessLimit) {
- int count = mExcludeEmptyApp.size();
- boolean mExclude = false;
- if(("true".equals(SystemProperties.get("ro.config.low_ram", "false")))
- ||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false"))))
- {
- for (int k=0; k<count; k++) {
- if(app.processName != null && app.processName.contains(mExcludeEmptyApp.get(k)))
- {
- if(DEBUG_LOWMEM)Slog.d("Tower","------shouldExcludeCachedApp App= "+app.processName);
- mExclude = true;
- break;
- }
- }
- }
- if(!mExclude)//do not kill phone, which would cause 3g dongle can not use, do not kill media which would cause mediaprovider stale
- app.kill("cached #" + numCached, true);
- }
- break;
- case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
- if (numEmpty > ProcessList.TRIM_EMPTY_APPS
- && app.lastActivityTime < oldTime) {
- app.kill("empty for "
- + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
- / 1000) + "s", true);
- } else {
- numEmpty++;
- if (numEmpty > emptyProcessLimit) {
- int count = mExcludeEmptyApp.size();
- boolean mExclude = false;
- if(("true".equals(SystemProperties.get("ro.config.low_ram", "false")))
- ||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false"))))
- {
- for (int k=0; k<count; k++) {
- if(app.processName != null && app.processName.contains(mExcludeEmptyApp.get(k)))
- {
- if(DEBUG_LOWMEM)Slog.d("Tower","------shouldExcludeEmptyApp App= "+app.processName);
- mExclude = true;
- break;
+ switch (app.curProcState) {
+ case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
+ case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
+ mNumCachedHiddenProcs++;
+ numCached++;
+
+ if (numCached > cachedProcessLimit) {
+ int count = mExcludeEmptyApp.size();
+ boolean mExclude = false;
+
+ if(SystemProperties.getBoolean("ro.config.low_ram", false) ||
+ SystemProperties.getBoolean("ro.mem_optimise.enable", false)) {
+ for (int k=0; k<count; k++) {
+ if(app.processName != null && app.processName.contains(mExcludeEmptyApp.get(k))) {
+ if(DEBUG_LOWMEM) {
+ Slog.d(DEBUG_LOWMEM_TAG,"------shouldExcludeCachedApp App= "+app.processName);
+ }
+
+ mExclude = true;
+ break;
+ }
+ }
}
- }
- }
- if(!mExclude)//do not kill phone, which would cause 3g dongle can not use, do not kill media which would cause mediaprovider stale
- app.kill("empty #" + numEmpty, true);
- }
+ if(!mExclude) {
+ app.kill("cached #" + numCached, true);
+ }//do not kill phone, which would cause 3g dongle can not use, do not kill media which would cause mediaprovider stale
+
+ }
+ break;
+
+ case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
+ if (numEmpty > ProcessList.TRIM_EMPTY_APPS &&
+ app.lastActivityTime < oldTime) {
+ app.kill("empty for "
+ + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
+ / 1000) + "s", true);
+ } else {
+ numEmpty++;
+ if (numEmpty > emptyProcessLimit) {
+ int count = mExcludeEmptyApp.size();
+ boolean mExclude = false;
+
+ if(SystemProperties.getBoolean("ro.config.low_ram", false) ||
+ SystemProperties.getBoolean("ro.mem_optimise.enable", false)) {
+ for (int k=0; k<count; k++) {
+ if(app.processName != null && app.processName.contains(mExcludeEmptyApp.get(k))) {
+ if (DEBUG_LOWMEM) {
+ Slog.d(DEBUG_LOWMEM_TAG,"------shouldExcludeEmptyApp App= "+app.processName);
+ }
+ mExclude = true;
+ break;
+ }
+ }
+ }
+
+ //do not kill phone, which would cause 3g dongle can not use, do not kill media which would cause mediaprovider stale
+ if (!mExclude)
+ app.kill("empty #" + numEmpty, true);
+ }
}
break;
+
default:
mNumNonCachedProcs++;
break;
@@ -19524,6 +19766,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
}
}
+
mLastMemoryLevel = memFactor;
mLastNumProcesses = mLruProcesses.size();
boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
@@ -19545,18 +19788,21 @@ public final class ActivityManagerService extends ActivityManagerNative
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
break;
}
- int factor = numTrimming/3;
+ int factor = numTrimming / 3;
int minFactor = 2;
if (mHomeProcess != null) minFactor++;
if (mPreviousProcess != null) minFactor++;
- if (factor < minFactor) factor = minFactor;
+ if (factor < minFactor)
+ factor = minFactor;
+
int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
- for (int i=N-1; i>=0; i--) {
+ for (int i = N - 1; i >= 0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (allChanged || app.procStateChanged) {
setProcessTrackerStateLocked(app, trackerMemFactor, now);
app.procStateChanged = false;
}
+
if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
&& !app.killedByAm) {
if (app.trimMemoryLevel < curLevel && app.thread != null) {
@@ -19566,7 +19812,8 @@ public final class ActivityManagerService extends ActivityManagerNative
app.thread.scheduleTrimMemory(curLevel);
} catch (RemoteException e) {
}
- if (false) {
+
+ if (false) {
// For now we won't do this; our memory trimming seems
// to be good enough at this point that destroying
// activities causes more harm than good.
@@ -19580,6 +19827,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
+
app.trimMemoryLevel = curLevel;
step++;
if (step >= factor) {
@@ -19593,6 +19841,7 @@ public final class ActivityManagerService extends ActivityManagerNative
break;
}
}
+
} else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
&& app.thread != null) {
@@ -19606,6 +19855,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+
} else {
if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
|| app.systemNoUi) && app.pendingUiClean) {
@@ -19640,8 +19890,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mLowRamStartTime != 0) {
mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
mLowRamStartTime = 0;
- }
- for (int i=N-1; i>=0; i--) {
+ }
+ for (int i = N-1; i >= 0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (allChanged || app.procStateChanged) {
setProcessTrackerStateLocked(app, trackerMemFactor, now);
@@ -19697,7 +19947,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
});
}
-
+
if (DEBUG_OOM_ADJ) {
final long duration = SystemClock.uptimeMillis() - now;
if (false) {
@@ -19708,7 +19958,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
-
+
final void trimApplications() {
synchronized (this) {
int i;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 7f17f77..2bf278e 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -77,6 +77,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
+
/**
* State and management of a single stack of activities.
*/
@@ -996,7 +997,8 @@ final class ActivityStack {
private void completePauseLocked(boolean resumeNext) {
ActivityRecord prev = mPausingActivity;
- if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
+ if (DEBUG_PAUSE)
+ Slog.v(TAG_PAUSE, "Complete pause: " + prev);
if (prev != null) {
prev.state = ActivityState.PAUSED;
@@ -1037,39 +1039,110 @@ final class ActivityStack {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
prev = null;
}
+
// It is possible the activity was freezing the screen before it was paused.
// In that case go ahead and remove the freeze this activity has on the screen
// since it is no longer visible.
prev.stopFreezingScreenLocked(true /*force*/);
- if(("true".equals(SystemProperties.get("ro.config.low_ram", "false")) || "vr".equals(SystemProperties.get("ro.target.product","unknown" ))) && (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false"))))
- {
- ActivityStack topStack = mStackSupervisor.getFocusedStack();
- ActivityRecord next = topStack.topRunningActivityLocked(null);
- if(next == null)
- next = mResumingActivity;
-
-
- if(DEBUG_LOWMEM)Slog.d("Tower","-----------prev= "+prev+" next= "+next);
- if((prev.task != next.task)&&(!prev.packageName.equals(next.packageName)))
- {
- String prevstring = prev.toString();
- if(!shouldExcludePrevApp(prevstring))
- {
- String nextstring = next.toString();
- if(!shouldExcludeNextApp(nextstring))
- {
- if(DEBUG_LOWMEM)Slog.d("Tower","------pause packages "+prevstring+" next = "+ nextstring);
- mService.killAppAtUsersRequest(prev.app, null);
+
+ /* // Modify Tower 20181008 restore
+ if(false &&
+ ("true".equals(SystemProperties.get("ro.config.low_ram", "false")) || "vr".equals(SystemProperties.get("ro.target.product","unknown" ))) &&
+ (!"true".equals(SystemProperties.get("sys.cts_gts.status", "false")))) {
+
+ ActivityStack topStack = mStackSupervisor.getFocusedStack();
+ ActivityRecord next = topStack.topRunningActivityLocked(null);
+ if(next == null)
+ next = mResumingActivity;
+
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","-----------prev= " + prev + " next= " + next);
+
+ if((prev.task != next.task) &&
+ (!prev.packageName.equals(next.packageName))) {
+
+ String prevstring = prev.toString();
+ if(!shouldExcludePrevApp(prevstring)) {
+ String nextstring = next.toString();
+ if(!shouldExcludeNextApp(nextstring)) {
+ String curName = prev.packageName;
+ nextstring = next.packageName;
+
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","------pause packages "+prevstring+" next = "+ nextstring+" = "+prev.packageName+" = "+next.packageName);
+
+ boolean isKillWyt = ("com.wyt.cl".equals(curName)
+ ||"com.wyt.zxp.xx".equals(curName)
+ ||"air.wyt.modloader".equals(curName)
+ ||"com.wyt.gelingpad.appstore_student".equals(curName)
+ ||"com.wyt.xq.flash".equals(curName)
+ ||"air.com.wyt.EnglishABC".equals(curName)
+ ||"air.com.wyt.QuWeiXueHanZi".equals(curName)
+ ||"com.wyt.sxjh".equals(curName)
+ ||"air.com.wyt.ChangErGeShiZi".equals(curName)
+ ||"com.wyt.download".equals(curName)
+ ||"air.com.wyt.TongBuDianDu".equals(curName)) ? false : true;
+
+ if(!curName.equals("com.smartdream.luqiyalauncher")
+ &&!(!isKillWyt &&
+ ("com.wyt.cl".equals(nextstring)||
+ "com.wyt.zxp.xx".equals(nextstring)||
+ "air.wyt.modloader".equals(nextstring)||
+ "com.wyt.gelingpad.appstore_student".equals(nextstring) ||
+ "com.wyt.xq.flash".equals(nextstring)||
+ "air.com.wyt.EnglishABC".equals(nextstring) ||
+ "air.com.wyt.QuWeiXueHanZi".equals(nextstring) ||
+ "com.wyt.sxjh".equals(nextstring)||
+ "air.com.wyt.ChangErGeShiZi".equals(nextstring)||
+ "com.wyt.download".equals(nextstring)||
+ "air.com.wyt.TongBuDianDu".equals(nextstring)))) {
+ Slog.d("Tower"," come here "+ prev.packageName);
+ mService.killAppAtUsersRequest(prev.app, null);
+ }
+ }
+ }
+ }
+
+ if(mService.mGameMap.get(prev.processName) != null) {
+ mService.killAllBackgroundProcesses();
+ if(DEBUG_LOWMEM)
+ Slog.v("Tower", "----clean memory for stop " + prev.processName);
+ }
+ }
+
+ mPausingActivity = null;
+ }
+ */
+
+ if((!SystemProperties.getBoolean("sys.cts_gts.status", false)) &&
+ (SystemProperties.getBoolean("ro.config.low_ram", false)) || "vr".equals(SystemProperties.get("ro.target.product","unknown" ))) {
+ ActivityStack topStack = mStackSupervisor.getFocusedStack();
+ ActivityRecord next = topStack.topRunningActivityLocked(null);
+ if(next == null)
+ next = mResumingActivity;
+
+
+ if(DEBUG_LOWMEM)
+ Slog.d("Tower","-----------prev= " + prev + " next= " + next);
+
+ if((prev.task != next.task) && (!prev.packageName.equals(next.packageName))) {
+ String prevstring = prev.toString();
+ if(!shouldExcludePrevApp(prevstring)) {
+ String nextstring = next.toString();
+ if(!shouldExcludeNextApp(nextstring)) {
+ if(DEBUG_LOWMEM) Slog.d("Tower","------pause packages " + prevstring + " next = " + nextstring);
+ mService.killAppAtUsersRequest(prev.app, null);
+ }
+ }
+ }
+
+ if(mService.mGameMap.get(prev.processName) != null) {
+ mService.killAllBackgroundProcesses();
+ if(DEBUG_LOWMEM) Slog.v("Tower", "----clean memory for stop " + prev.processName);
}
}
- }
- if(mService.mGameMap.get(prev.processName) != null)
- {
- mService.killAllBackgroundProcesses();
- if(DEBUG_LOWMEM)Slog.v("Tower", "----clean memory for stop " + prev.processName);
- }
- }
- mPausingActivity = null;
+
+ mPausingActivity = null;
}
if (resumeNext) {
@@ -1590,37 +1663,35 @@ final class ActivityStack {
}
boolean shouldExcludePrevApp(String prevApp) {
- if(prevApp == null)
- {
- if(DEBUG_LOWMEM)Slog.d("Tower","---prevApp is null in shouldExcludePrevApp--");
- return false;
+ if(prevApp == null) {
+ if(DEBUG_LOWMEM)Slog.d("Tower","---prevApp is null in shouldExcludePrevApp--");
+ return false;
}
- int N = mService.mExcludePrevApp.size();
- for (int i=0; i<N; i++) {
- if(prevApp.contains(mService.mExcludePrevApp.get(i)))
- {
- if(DEBUG_LOWMEM)Slog.d("Tower","------shouldExcludePrevApp prevApp= "+prevApp);
- return true;
- }
- }
+
+ int N = mService.mExcludePrevApp.size();
+ for (int i=0; i<N; i++) {
+ if(prevApp.contains(mService.mExcludePrevApp.get(i))) {
+ if(DEBUG_LOWMEM)Slog.d("Tower","------shouldExcludePrevApp prevApp= "+prevApp);
+ return true;
+ }
+ }
return false;
}
boolean shouldExcludeNextApp(String nextApp) {
- if(nextApp == null)
- {
- if(DEBUG_LOWMEM)Slog.d("Tower","---nextApp is null in shouldExcludeNextApp--");
- return false;
- }
- int N = mService.mExcludeNextApp.size();
- for (int i=0; i<N; i++) {
- if(nextApp.contains(mService.mExcludeNextApp.get(i)))
- {
- if(DEBUG_LOWMEM)Slog.d("Tower","------shouldExcludeNextApp nextApp= "+nextApp);
- return true;
- }
- }
+ if(nextApp == null) {
+ if(DEBUG_LOWMEM)Slog.d("Tower","---nextApp is null in shouldExcludeNextApp--");
return false;
+ }
+
+ int N = mService.mExcludeNextApp.size();
+ for (int i=0; i<N; i++) {
+ if(nextApp.contains(mService.mExcludeNextApp.get(i))) {
+ if(DEBUG_LOWMEM)Slog.d("Tower","------shouldExcludeNextApp nextApp= "+nextApp);
+ return true;
+ }
+ }
+ return false;
}
@@ -1747,7 +1818,7 @@ final class ActivityStack {
mStackSupervisor.mWaitingVisibleActivities.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
- mResumingActivity = next;
+ mResumingActivity = next;
// If we are currently pausing an activity, then don't do anything
// until that is done.
@@ -1922,6 +1993,9 @@ final class ActivityStack {
} else {
next.clearOptionsLocked();
}
+
+ // Modify Yuandan 20190822, by Tower What is?
+ mWindowManager.updateRotationUnchecked(true,true);
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
@@ -2071,7 +2145,9 @@ final class ActivityStack {
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
+
mStackSupervisor.startSpecificActivityLocked(next, true, true);
+
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
@@ -3587,89 +3663,95 @@ final class ActivityStack {
}
}
- boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
- removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
- removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app,
- "mStoppingActivities");
- removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
- "mGoingToSleepActivities");
- removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app,
- "mWaitingVisibleActivities");
- removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
- "mFinishingActivities");
-
- boolean hasVisibleActivities = false;
-
- // Clean out the history list.
- int i = numActivities();
- if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
- "Removing app " + app + " from history with " + i + " entries");
- for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
- for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
- final ActivityRecord r = activities.get(activityNdx);
- --i;
- if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
- "Record #" + i + " " + r + ": app=" + r.app);
- if (r.app == app) {
- if (r.visible) {
- hasVisibleActivities = true;
- }
- final boolean remove;
- if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
- // Don't currently have state for the activity, or
- // it is finishing -- always remove it.
- remove = true;
- } else if (r.launchCount > 2 &&
- r.lastLaunchTime > (SystemClock.uptimeMillis()-60000)) {
- // We have launched this activity too many times since it was
- // able to run, so give up and remove it.
- remove = true;
- } else {
- // The process may be gone, but the activity lives on!
- remove = false;
- }
- if (remove) {
- if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
- "Removing activity " + r + " from stack at " + i
- + ": haveState=" + r.haveState
- + " stateNotNeeded=" + r.stateNotNeeded
- + " finishing=" + r.finishing
- + " state=" + r.state + " callers=" + Debug.getCallers(5));
- if (!r.finishing) {
- Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
- EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
- r.userId, System.identityHashCode(r),
- r.task.taskId, r.shortComponentName,
- "proc died without state saved");
- if (r.state == ActivityState.RESUMED) {
- mService.updateUsageStats(r, false);
- }
- }
- } else {
- // We have the current state for this activity, so
- // it can be restarted later when needed.
- if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
- if (DEBUG_APP) Slog.v(TAG_APP,
- "Clearing app during removeHistory for activity " + r);
- r.app = null;
- r.nowVisible = false;
- if (!r.haveState) {
- if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
- "App died, clearing saved state of " + r);
- r.icicle = null;
- }
- }
- cleanUpActivityLocked(r, true, true);
- if (remove) {
- removeActivityFromHistoryLocked(r, "appDied");
- }
- }
- }
- }
-
- return hasVisibleActivities;
- }
+ boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
+ removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
+ removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app,
+ "mStoppingActivities");
+ removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
+ "mGoingToSleepActivities");
+ removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app,
+ "mWaitingVisibleActivities");
+ removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
+ "mFinishingActivities");
+
+ boolean hasVisibleActivities = false;
+
+ // Clean out the history list.
+ int i = numActivities();
+ if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
+ "Removing app " + app + " from history with " + i + " entries");
+
+ for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+ final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+ for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+ final ActivityRecord r = activities.get(activityNdx);
+ --i;
+ if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
+ "Record #" + i + " " + r + ": app=" + r.app);
+
+ final boolean remove;
+
+ if (r.app == app) {
+ if (r.visible) {
+ hasVisibleActivities = true;
+ }
+
+ // Modify yuandan 20190822, by Tower Why? for kill process.
+ if ((!r.haveState && !r.stateNotNeeded) || r.finishing || r.app.killedByAm) {
+ // Don't currently have state for the activity, or
+ // it is finishing -- always remove it.
+ remove = true;
+ } else if (r.launchCount > 2 &&
+ r.lastLaunchTime > (SystemClock.uptimeMillis()-60000)) {
+ // We have launched this activity too many times since it was
+ // able to run, so give up and remove it.
+ remove = true;
+ } else {
+ // The process may be gone, but the activity lives on!
+ remove = false;
+ }
+
+ if (remove) {
+ if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
+ "Removing activity " + r + " from stack at " + i
+ + ": haveState=" + r.haveState
+ + " stateNotNeeded=" + r.stateNotNeeded
+ + " finishing=" + r.finishing
+ + " state=" + r.state + " callers=" + Debug.getCallers(5));
+ if (!r.finishing) {
+ Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
+ EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
+ r.userId, System.identityHashCode(r),
+ r.task.taskId, r.shortComponentName,
+ "proc died without state saved");
+ if (r.state == ActivityState.RESUMED) {
+ mService.updateUsageStats(r, false);
+ }
+ }
+ } else {
+ // We have the current state for this activity, so
+ // it can be restarted later when needed.
+ if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
+ if (DEBUG_APP) Slog.v(TAG_APP,
+ "Clearing app during removeHistory for activity " + r);
+ r.app = null;
+ r.nowVisible = false;
+ if (!r.haveState) {
+ if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
+ "App died, clearing saved state of " + r);
+ r.icicle = null;
+ }
+ }
+
+ cleanUpActivityLocked(r, true, true);
+ if (remove) {
+ removeActivityFromHistoryLocked(r, "appDied");
+ }
+ }
+ }
+ }
+ return hasVisibleActivities;
+ }
final void updateTransitLocked(int transit, Bundle options) {
if (options != null) {
@@ -4373,6 +4455,7 @@ final class ActivityStack {
}
}
mTaskHistory.remove(task);
+ mService.abandonAudioFocusFromHelper();
updateTaskMovement(task, true);
if (notMoving && task.mActivities.isEmpty()) {
@@ -4428,6 +4511,7 @@ final class ActivityStack {
void addTask(final TaskRecord task, final boolean toTop, boolean moving) {
task.stack = this;
if (toTop) {
+ mService.requestAudioFocusFromHelper(task.affinity);
insertTaskAtTop(task, null);
} else {
mTaskHistory.add(0, task);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
old mode 100644
new mode 100755
index 17a86ca..86f9b9a
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -458,6 +458,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
+ " new=" + mFocusedStack);
stacks.remove(mHomeStack);
stacks.add(toFront ? topNdx : 0, mHomeStack);
+
+ // Modify Tower 20200526. enter home killer not need app.
+ mService.updateSmartDreamOomAdjLocked();
}
if (lastFocusedStack != null) {
@@ -929,6 +932,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
Bundle options, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
+
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -1367,7 +1371,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
-
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
@@ -1392,7 +1395,16 @@ public final class ActivityStackSupervisor implements DisplayListener {
// restart the application.
}
- mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
+ // Modify Tower 20181022
+ try {
+ if (getStatusBarService() != null) {
+ getStatusBarService().scheduleInterludeAnimation(r.packageName, r.isHomeActivity()); // Intent Caller Start
+ }
+ } catch (RemoteException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
@@ -1405,7 +1417,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
ActivityContainer container, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
-
+
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
@@ -1818,19 +1830,20 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
final TaskRecord task = r.task;
if (task == null || task.stack == null) {
- Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task);
+ Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task);
return false;
}
task.stack.moveToFront(reason);
return true;
}
+ // param r is current
+ // param sourceRecord is caller
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
final Intent intent = r.intent;
final int callingUid = r.launchedFromUid;
-
// In some flows in to this function, we retrieve the task record and hold on to it
// without a lock before calling back in to here... so the task at this point may
// not actually be in recents. Check for that, and if it isn't in recents just
@@ -1839,7 +1852,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
inTask = null;
}
-
+
final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
old mode 100644
new mode 100755
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
old mode 100644
new mode 100755
index 0e24952..a3300d4
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -45,7 +45,7 @@ final class ProcessList {
// The minimum time we allow between crashes, for us to consider this
// application to be bad and stop and its services and reject broadcasts.
- static final int MIN_CRASH_INTERVAL = 60*1000;
+ static final int MIN_CRASH_INTERVAL = 60 * 1000;
// OOM adjustments for processes in various states:
@@ -57,7 +57,7 @@ final class ProcessList {
// This is a process only hosting activities that are not visible,
// so it can be killed without any disruption.
static final int CACHED_APP_MAX_ADJ = 15;
- static final int CACHED_APP_MIN_ADJ = 9;
+ static final int CACHED_APP_MIN_ADJ = 5; // Modify Tower 9 -> 0 -> 9 -> 5
// The B list of SERVICE_ADJ -- these are the old and decrepit
// services that aren't as shiny and interesting as the ones in the A list.
diff --git a/services/core/java/com/android/server/am/killer/IdentityManager.java b/services/core/java/com/android/server/am/killer/IdentityManager.java
new file mode 100755
index 0000000..9d90fb9
--- /dev/null
+++ b/services/core/java/com/android/server/am/killer/IdentityManager.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 20200526
+ * iFinelio Tower
+ *
+ * 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 android.util.Slog;
+import android.util.ArrayMap;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import android.util.PropertiesXmlParser;
+
+public class IdentityManager {
+ private static final String TAG = "SmartDreamIDM";
+
+ public static final int IDENTITY_SYSTEM = 1 << 0;
+ public static final int IDENTITY_LAUNCHER = 1 << 2;
+ public static final int IDENTITY_PRIVILEGE = 1 << 1;
+ public static final int IDENTITY_VOICESERVICE = 1 << 4;
+
+ // Modify Tower 20190606, SmartDream custom kill policy object define
+ private Map<String, List<String>> mOomKillProcPolicy = null;
+
+ // custom launcher
+ private List<String> defaultLauncherlist = null;
+
+ // custom proc protect
+ private List<String> defaultPrivProclist = null;
+
+ // only system
+ private List<String> defaultSystemProcesslist = null;
+
+ // Usually a voice service
+ private List<String> defaultVoiceServicelist = null;
+
+ // This is in killer after need restart proc list. Usually for system applications
+ private List<String> defaultAllowRestartlist = null;
+
+ IdentityManager() {
+ analysisIdentityConfigXml();
+ }
+
+ public boolean verifyIdentity(int type, String name) {
+ switch (type) {
+ case IDENTITY_SYSTEM:
+ return PropertiesXmlParser.checkMatch(defaultSystemProcesslist, name);
+
+ case IDENTITY_LAUNCHER:
+ return PropertiesXmlParser.checkMatch(defaultLauncherlist, name);
+
+ case IDENTITY_PRIVILEGE:
+ return PropertiesXmlParser.checkMatch(defaultPrivProclist, name);
+
+ case IDENTITY_VOICESERVICE:
+ return PropertiesXmlParser.checkMatch(defaultVoiceServicelist, name);
+
+ default:
+ return false;
+ }
+ }
+
+ void analysisIdentityConfigXml() {
+ if (null == mOomKillProcPolicy) {
+ // TODO: if add nowlist, must be in Arrays.asList add it!!!
+ mOomKillProcPolicy = new PropertiesXmlParser("/system/etc/xml/policyPrivilegeProc.xml",
+ new ArrayList<>(Arrays.asList("launcher_list", "voiceservice_list", "privproc_list",
+ "systemproc_list", "allowrestart_list", "floatview_list")),
+ PropertiesXmlParser.ATTR_ASSET_PACKAGE).getResult();
+
+ defaultLauncherlist = PropertiesXmlParser.getXmlPolicyList(mOomKillProcPolicy, "launcher_list",
+ new ArrayList<>(Arrays.asList(
+ "com.smartdream.luqiyalauncher",
+ "com.example.launcher_a9_zlkc",
+ "com.example.launcher_a10_zlkc",
+ "com.example.smartdream.thinkingmachine")));
+
+ defaultVoiceServicelist = PropertiesXmlParser.getXmlPolicyList(mOomKillProcPolicy, "voiceservice_list",
+ new ArrayList<>(Arrays.asList(
+ "com.aispeech.kui",
+ "com.airiche.smartdream",
+ "com.turing.turingsdksample",
+ "com.alibaba.ailabs.genie.smartapp")));
+
+ defaultPrivProclist = PropertiesXmlParser.getXmlPolicyList(mOomKillProcPolicy, "privproc_list",
+ new ArrayList<>(Arrays.asList(
+ "com.adups.fota" ,
+ "com.adups.fota.sysoper",
+ "com.turing.padbot",
+ "com.tencent.deviceapp",
+ "com.tencent.deviceapp:video",
+ "com.cghs.stresstest")));
+
+ defaultSystemProcesslist = PropertiesXmlParser.getXmlPolicyList(mOomKillProcPolicy, "systemproc_list",
+ new ArrayList<>(Arrays.asList(
+ "system",
+ "android.process.media",
+ "com.android.systemui2",
+ "com.android.inputmethod.pinyin",
+ "com.android.systemui",
+ "com.android.documentsui",
+ "com.android.defcontainer",
+ "com.android.packageinstaller",
+ "com.android.providers.media",
+ "com.android.providers.downloads.ui")));
+
+ if (true) {
+ Slog.d(TAG, "Debug printf list : ");
+ Slog.d(TAG, " launcher : ");
+ for (String value : defaultLauncherlist) {
+ Slog.d(TAG, " val = " + value);
+ }
+ Slog.d(TAG, " ");
+
+ Slog.d(TAG, " voiceservice : ");
+ for (String value : defaultVoiceServicelist) {
+ Slog.d(TAG, " val = " + value);
+ }
+ Slog.d(TAG, " ");
+
+ Slog.d(TAG, " privproc : ");
+ for (String value : defaultPrivProclist) {
+ Slog.d(TAG, " val = " + value);
+ }
+ Slog.d(TAG, " ");
+
+ Slog.d(TAG, " SystemProc : ");
+ for (String value : defaultSystemProcesslist) {
+ Slog.d(TAG, " val = " + value);
+ }
+ Slog.d(TAG, " ");
+ Slog.d(TAG, "Debug printf end!. ");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/am/killer/SmartDreamLMKManagerService.java b/services/core/java/com/android/server/am/killer/SmartDreamLMKManagerService.java
new file mode 100755
index 0000000..40ad987
--- /dev/null
+++ b/services/core/java/com/android/server/am/killer/SmartDreamLMKManagerService.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 20200526
+ * iFinelio Tower
+ *
+ * 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 android.app.AppOpsManager;
+import android.appwidget.AppWidgetManager;
+import android.util.ArrayMap;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IAppOpsService;
+import com.android.internal.app.ProcessStats;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.ProcessCpuTracker;
+import com.android.internal.os.TransferPipe;
+import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.MemInfoReader;
+import com.android.internal.util.Preconditions;
+import com.android.server.AppOpsService;
+import com.android.server.AttributeCache;
+import com.android.server.IntentResolver;
+import com.android.internal.app.ProcessMap;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManagerNative;
+import android.content.pm.ApplicationInfo;
+import android.app.PendingIntent;
+import android.app.backup.IBackupManager;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.os.Environment;
+import android.os.Process;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.util.EventLog;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+import java.util.Map;
+
+import android.util.PrintWriterPrinter;
+
+
+// inner class
+import com.android.server.am.SmartDreamLMKManagerService.UIDGroup;
+
+public final class SmartDreamLMKManagerService {
+ private static final String TAG = "SmartDreamLMK";
+
+ private static boolean DEBUG = false;
+ private static boolean ENABLE_KILLER = true;
+ private static boolean ENABLE_FLITER = true;
+
+ private final ActivityManagerService mAMS;
+
+ private IdentityManager mIDM;
+ private final ArrayMap<Integer, UIDGroup> mSmartDreamOOMap;
+
+ public SmartDreamLMKManagerService(ActivityManagerService am) {
+ mAMS = am;
+
+ mIDM = new IdentityManager();
+ mSmartDreamOOMap = new ArrayMap<Integer, UIDGroup>();
+ }
+
+ private ProcessRecord getTopApp() {
+ final ActivityRecord TOP_ACT = mAMS.resumedAppLocked();
+ final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
+
+ return TOP_APP;
+ }
+
+ private boolean isTop(ApplicationInfo info) {
+ final ProcessRecord TOP_APP = getTopApp();
+
+ if ((TOP_APP != null) && (info.uid == TOP_APP.uid))
+ return true;
+
+ return false;
+ }
+
+ private boolean isSystem(ProcessRecord pr) {
+ if (pr.persistent) {
+ return true;
+ }
+
+ if (pr.uid == Process.SYSTEM_UID) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean filterSmartDreamContentProviderProcess(String processName, ApplicationInfo info, String hostingType) {
+ if (("broadcast".equals(hostingType)) ||
+ ("content provider".equals(hostingType))) {
+ dumpi("Content Provider dont start because for filter: " + info.uid + "/" + info.processName);
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean filterSmartDreamServiceProcess(String processName, ApplicationInfo info, String hostingType) {
+ if (("service".equals(hostingType)) &&
+ ((info.flags & ApplicationInfo.FLAG_MULTIARCH) == 0)) {
+ dumpi("service dont start auto because for filter: " + info.uid + "/" + info.processName);
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean filterSmartDreamBroadcastProcess(String processName, ApplicationInfo info, String hostingType) {
+ if (("broadcast".equals(hostingType)) &&
+ ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0)) {
+ dumpi("third part process dont start for broadcast: " + info.uid + "/" + info.processName);
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean verifyIdentity(int type, String name) {
+ return mIDM.verifyIdentity(type, name);
+ }
+
+ public boolean filterMatrix(String processName, ApplicationInfo info, String hostingType) {
+ if (!ENABLE_FLITER) {
+ return false;
+ }
+
+ if (isTop(info)) {
+ return false;
+ }
+
+ if (verifyIdentity(IdentityManager.IDENTITY_SYSTEM, processName) ||
+ verifyIdentity(IdentityManager.IDENTITY_PRIVILEGE, processName) ||
+ verifyIdentity(IdentityManager.IDENTITY_VOICESERVICE, processName)) {
+ return false;
+ }
+
+ if (filterSmartDreamContentProviderProcess(processName, info, hostingType)) {
+ return true;
+ }
+
+ if (filterSmartDreamServiceProcess(processName, info, hostingType)) {
+ return true;
+ }
+
+ if (filterSmartDreamBroadcastProcess(processName, info, hostingType)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean filterSmartDreamAllowResetProcess(String name) {
+ if (!ENABLE_FLITER) {
+ return false;
+ }
+
+ if (!mIDM.verifyIdentity(IdentityManager.IDENTITY_SYSTEM, name)) {
+ dumpi("reject app reset: " + name);
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean filterSmartDreamOOMProcess(ProcessRecord pr) {
+ if (!ENABLE_KILLER) {
+ return true;
+ }
+
+ // filter system & priv app.
+ // allow persistent @AMS::newProcessRecordLocked() by SmartDreamLMK;
+ if (isSystem(pr)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public void addSmartDreamOomAdjLocked(ProcessRecord pr) {
+ if (filterSmartDreamOOMProcess(pr)) {
+ return;
+ }
+
+ Integer uid = new Integer(pr.uid);
+ if (mSmartDreamOOMap.get(uid) == null) {
+ UIDGroup ug = new UIDGroup(uid, pr);
+ mSmartDreamOOMap.put(uid, ug);
+ } else {
+ UIDGroup sug = mSmartDreamOOMap.get(uid);
+ sug.add(pr);
+ }
+ }
+
+ public static final int TYPE_UNKNOWN = -1;
+ public static final int TYPE_HOME_STATE = 0;
+ public static final int TYPE_GAME_STATE = 1;
+ public void updateSmartDreamOomAdjLocked() {
+ updateSmartDreamOomAdjLocked(TYPE_HOME_STATE);
+ }
+
+ public void updateSmartDreamOomAdjLocked(int type) {
+ final ProcessRecord TOP_APP = getTopApp();
+
+ if (TOP_APP == null || mSmartDreamOOMap.isEmpty()) {
+ return;
+ }
+
+ switch (type) {
+ // Home Mode
+ // background process long time not actives. kill redundant process.
+ // if process exist music actives, then retain.
+ case TYPE_UNKNOWN:
+ case TYPE_HOME_STATE :
+ for (Integer key : mSmartDreamOOMap.keySet()) {
+ if (key != null) {
+ UIDGroup sug = mSmartDreamOOMap.get(key);
+ dumpi("kill processName=" + sug.getName());
+
+ for (ProcessRecord pr : sug.getList()) {
+ mAMS.removeProcessLocked(pr, true, false, "SmartDream Home OOM Policy.");
+ }
+
+ sug.clear();
+ }
+ }
+ mSmartDreamOOMap.clear();
+ break;
+
+ case TYPE_GAME_STATE:
+ // Game Mode
+ // when memory tension, kill redundant process.
+ // if process exist music actives, then retain.
+ for (Integer key : mSmartDreamOOMap.keySet()) {
+ if ((key != null) && (key != TOP_APP.uid)) {
+ UIDGroup sug = mSmartDreamOOMap.get(key);
+ dumpi("kill processName=" + sug.getName());
+
+ for (ProcessRecord pr : sug.getList()) {
+ pr.kill("SmartDream Game OOM Policy.", true);
+ }
+
+ sug.clear();
+ mSmartDreamOOMap.remove(key);
+ }
+ }
+ break;
+ }
+ }
+
+ class UIDGroup {
+ private ArrayList<ProcessRecord> group;
+ private Integer uid;
+ private String groupName;
+ private boolean isActivites = false;
+
+ UIDGroup(Integer uid, ProcessRecord pr) {
+ group = new ArrayList<ProcessRecord>();
+ dumpi("new UidGroup <"+ uid + "> (" + pr.processName + ")");
+
+ this.uid = uid;
+ this.groupName = pr.processName;
+ group.add(pr);
+ }
+
+ public boolean isActivites() {
+ return isActivites;
+ }
+
+ public int getUid() {
+ return uid;
+ }
+
+ public String getName() {
+ return groupName;
+ }
+
+ public boolean add(ProcessRecord pr) {
+ if ((pr != null) && (group.indexOf(pr) == -1)) {
+ dumpi("add UidGroup <" + uid + "> (" + this.groupName + ") + " + pr.processName);
+ group.add(pr);
+ return true;
+ }
+
+ return false;
+ }
+
+ public void remove() {
+
+ }
+
+ public void clear() {
+
+ }
+
+ public ArrayList<ProcessRecord> getList() {
+ return group;
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+
+ }
+ }
+
+ private void dumpe(String oops) {
+ Slog.e(TAG, oops);
+ }
+
+ private void dumpi(String oops) {
+ if (DEBUG) {
+ Slog.i(TAG, oops);
+ }
+ }
+
+ final void dumpInfo(PrintWriter pw) {
+ pw.print(" ");
+ pw.println("DEBUG: " + DEBUG);
+ pw.print(" ");
+ pw.println("KILLER: " + ENABLE_KILLER);
+ pw.print(" ");
+ pw.println("FLITER: " + ENABLE_FLITER);
+ pw.print(" ");
+ pw.println("SmartDreamOOMap: " + mSmartDreamOOMap.size());
+
+ for (Map.Entry<Integer, UIDGroup> entry : mSmartDreamOOMap.entrySet()){
+ Integer mapUid = entry.getKey();
+ ArrayList<ProcessRecord> mapList = entry.getValue().getList();
+ pw.print(" UID: <");
+ pw.print(mapUid);
+ pw.println(">");
+ for (ProcessRecord pr : mapList) {
+ pw.print(" ");
+ pw.print("[" + pr.persistent + "]");
+ pw.println(" " + pr.toShortString());
+ }
+ pw.println(" ");
+ }
+
+ pw.flush();
+ }
+
+ final boolean setSwitch(String k, boolean v) {
+ if ("debug".equals(k)) {DEBUG = v; return true;}
+ if ("killer".equals(k)) {ENABLE_KILLER = v; return true;}
+ if ("fliter".equals(k)) {ENABLE_FLITER = v; return true;}
+
+ return false;
+ }
+
+ final void dumpSmartDreamOOM(PrintWriter pw, String[] args) {
+ if (args == null || args.length == 1) {
+ dumpInfo(pw);
+ } else if ((args.length == 4) && "set".equals(args[1])) {
+ String key = args[2];
+ String value = args[3];
+ try {
+ if (!setSwitch(key, Boolean.valueOf(value))) {
+ pw.println("Unknown set option: " + key);
+ }
+ } catch (NumberFormatException ex) {
+ pw.println("Bad value: " + value);
+ }
+ } else {
+ pw.println("Dump SmartDream OOM Killer info");
+ pw.println(" set " );
+ }
+ }
+}