Android AMS - 系统级应用自启动控制 & 杀进程策略

Android AMS - 系统级应用自启动控制 & 杀进程策略

  • 前期说明
  • 原理
  • 代码修改

前期说明

  • 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  ");
+        }
+	}
+}

你可能感兴趣的:(Android)