Loading core/java/android/app/ActivityThread.java +25 −0 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.InetAddress; import java.text.DateFormat; import java.util.ArrayList; Loading Loading @@ -933,6 +934,13 @@ public final class ActivityThread { sendMessage(H.BIND_APPLICATION, data); } public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) { SomeArgs args = SomeArgs.obtain(); args.arg1 = entryPoint; args.arg2 = entryPointArgs; sendMessage(H.RUN_ISOLATED_ENTRY_POINT, args); } public final void scheduleExit() { sendMessage(H.EXIT_APPLICATION, null); } Loading Loading @@ -1516,6 +1524,7 @@ public final class ActivityThread { public static final int ATTACH_AGENT = 155; public static final int APPLICATION_INFO_CHANGED = 156; public static final int ACTIVITY_MOVED_TO_DISPLAY = 157; public static final int RUN_ISOLATED_ENTRY_POINT = 158; String codeToString(int code) { if (DEBUG_MESSAGES) { Loading Loading @@ -1573,6 +1582,7 @@ public final class ActivityThread { case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED"; case ATTACH_AGENT: return "ATTACH_AGENT"; case APPLICATION_INFO_CHANGED: return "APPLICATION_INFO_CHANGED"; case RUN_ISOLATED_ENTRY_POINT: return "RUN_ISOLATED_ENTRY_POINT"; } } return Integer.toString(code); Loading Loading @@ -1843,6 +1853,10 @@ public final class ActivityThread { mUpdatingSystemConfig = false; } break; case RUN_ISOLATED_ENTRY_POINT: handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1, (String[]) ((SomeArgs) msg.obj).arg2); break; } Object obj = msg.obj; if (obj instanceof SomeArgs) { Loading Loading @@ -6308,6 +6322,17 @@ public final class ActivityThread { return retHolder; } private void handleRunIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) { try { Method main = Class.forName(entryPoint).getMethod("main", String[].class); main.invoke(null, new Object[]{entryPointArgs}); } catch (ReflectiveOperationException e) { throw new AndroidRuntimeException("runIsolatedEntryPoint failed", e); } // The process will be empty after this method returns; exit the VM now. System.exit(0); } private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; Loading core/java/android/app/IApplicationThread.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ oneway interface IApplicationThread { boolean restrictedBackupMode, boolean persistent, in Configuration config, in CompatibilityInfo compatInfo, in Map services, in Bundle coreSettings, in String buildSerial); void runIsolatedEntryPoint(in String entryPoint, in String[] entryPointArgs); void scheduleExit(); void scheduleConfigurationChanged(in Configuration config); void scheduleServiceArgs(IBinder token, in ParceledListSlice args); Loading services/core/java/com/android/server/am/ActivityManagerService.java +29 −23 Original line number Diff line number Diff line Loading @@ -3704,6 +3704,8 @@ public class ActivityManagerService extends IActivityManager.Stub return null; } app.crashHandler = crashHandler; app.isolatedEntryPoint = entryPoint; app.isolatedEntryPointArgs = entryPointArgs; checkTime(startTime, "startProcess: done creating new process record"); } else { // If this is a new package in the process, add the package to the list Loading @@ -3726,8 +3728,7 @@ public class ActivityManagerService extends IActivityManager.Stub } checkTime(startTime, "startProcess: stepping in to startProcess"); startProcessLocked( app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); startProcessLocked(app, hostingType, hostingNameStr, abiOverride); checkTime(startTime, "startProcess: done starting proc!"); return (app.pid != 0) ? app : null; } Loading @@ -3738,12 +3739,11 @@ public class ActivityManagerService extends IActivityManager.Stub private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) { startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, null /* entryPoint */, null /* entryPointArgs */); startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */); } private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { String hostingNameStr, String abiOverride) { long startTime = SystemClock.elapsedRealtime(); if (app.pid > 0 && app.pid != MY_PID) { checkTime(startTime, "startProcess: removing from pids map"); Loading Loading @@ -3888,8 +3888,7 @@ public class ActivityManagerService extends IActivityManager.Stub + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; final String entryPoint = "android.app.ActivityThread"; Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + app.processName); checkTime(startTime, "startProcess: asking zygote to start proc"); Loading @@ -3898,12 +3897,12 @@ public class ActivityManagerService extends IActivityManager.Stub startResult = startWebView(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, entryPointArgs); app.info.dataDir, null, null); } else { startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, entryPointArgs); app.info.dataDir, invokeWith, null); } checkTime(startTime, "startProcess: returned from zygote!"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Loading Loading @@ -3936,9 +3935,9 @@ public class ActivityManagerService extends IActivityManager.Stub buf.append(app.processName); buf.append('/'); UserHandle.formatUid(buf, uid); if (!isActivityProcess) { if (app.isolatedEntryPoint != null) { buf.append(" ["); buf.append(entryPoint); buf.append(app.isolatedEntryPoint); buf.append("]"); } buf.append(" for "); Loading Loading @@ -3968,13 +3967,11 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized (mPidsSelfLocked) { this.mPidsSelfLocked.put(startResult.pid, app); if (isActivityProcess) { Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); msg.obj = app; mHandler.sendMessageDelayed(msg, startResult.usingWrapper ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); } } checkTime(startTime, "startProcess: done updating pids map"); } catch (RuntimeException e) { Slog.e(TAG, "Failure starting process " + app.processName, e); Loading Loading @@ -7005,7 +7002,11 @@ public class ActivityManagerService extends IActivityManager.Stub checkTime(startTime, "attachApplicationLocked: immediately before bindApplication"); mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app); if (app.instr != null) { if (app.isolatedEntryPoint != null) { // This is an isolated process which should just call an entry point instead of // being bound to an application. thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs); } else if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, Loading Loading @@ -12249,6 +12250,11 @@ public class ActivityManagerService extends IActivityManager.Stub r.persistent = true; r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; } if (isolated && isolatedUid != 0) { // Special case for startIsolatedProcess (internal only) - assume the process // is required by the system server to prevent it being killed. r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ; } addProcessNameLocked(r); return r; } Loading Loading @@ -12316,8 +12322,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { mPersistentStartingProcesses.add(app); startProcessLocked(app, "added application", customProcess != null ? customProcess : app.processName, abiOverride, null /* entryPoint */, null /* entryPointArgs */); customProcess != null ? customProcess : app.processName, abiOverride); } return app; Loading Loading @@ -22556,9 +22561,10 @@ public class ActivityManagerService extends IActivityManager.Stub break; } if (app.isolated && app.services.size() <= 0) { // If this is an isolated process, and there are no // services running in it, then the process is no longer if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) { // If this is an isolated process, there are no services // running in it, and it's not a special process with a // custom entry point, then the process is no longer // needed. We agressively kill these because we can by // definition not re-use the same process again, and it is // good to avoid having whatever code was running in them services/core/java/com/android/server/am/ProcessRecord.java +9 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.util.TimeUtils; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; /** * Full information about a particular process that Loading Loading @@ -174,6 +175,9 @@ final class ProcessRecord { // All ContentProviderRecord process is using final ArrayList<ContentProviderConnection> conProviders = new ArrayList<>(); String isolatedEntryPoint; // Class to run on start if this is a special isolated process. String[] isolatedEntryPointArgs; // Arguments to pass to isolatedEntryPoint's main(). boolean execServicesFg; // do we need to be executing services in the foreground? boolean persistent; // always keep this application running? boolean crashing; // are we in the process of crashing? Loading Loading @@ -379,6 +383,11 @@ final class ProcessRecord { if (whitelistManager) { pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager); } if (isolatedEntryPoint != null || isolatedEntryPointArgs != null) { pw.print(prefix); pw.print("isolatedEntryPoint="); pw.println(isolatedEntryPoint); pw.print(prefix); pw.print("isolatedEntryPointArgs="); pw.println(Arrays.toString(isolatedEntryPointArgs)); } if (activities.size() > 0) { pw.print(prefix); pw.println("Activities:"); for (int i=0; i<activities.size(); i++) { Loading Loading
core/java/android/app/ActivityThread.java +25 −0 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.InetAddress; import java.text.DateFormat; import java.util.ArrayList; Loading Loading @@ -933,6 +934,13 @@ public final class ActivityThread { sendMessage(H.BIND_APPLICATION, data); } public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) { SomeArgs args = SomeArgs.obtain(); args.arg1 = entryPoint; args.arg2 = entryPointArgs; sendMessage(H.RUN_ISOLATED_ENTRY_POINT, args); } public final void scheduleExit() { sendMessage(H.EXIT_APPLICATION, null); } Loading Loading @@ -1516,6 +1524,7 @@ public final class ActivityThread { public static final int ATTACH_AGENT = 155; public static final int APPLICATION_INFO_CHANGED = 156; public static final int ACTIVITY_MOVED_TO_DISPLAY = 157; public static final int RUN_ISOLATED_ENTRY_POINT = 158; String codeToString(int code) { if (DEBUG_MESSAGES) { Loading Loading @@ -1573,6 +1582,7 @@ public final class ActivityThread { case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED"; case ATTACH_AGENT: return "ATTACH_AGENT"; case APPLICATION_INFO_CHANGED: return "APPLICATION_INFO_CHANGED"; case RUN_ISOLATED_ENTRY_POINT: return "RUN_ISOLATED_ENTRY_POINT"; } } return Integer.toString(code); Loading Loading @@ -1843,6 +1853,10 @@ public final class ActivityThread { mUpdatingSystemConfig = false; } break; case RUN_ISOLATED_ENTRY_POINT: handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1, (String[]) ((SomeArgs) msg.obj).arg2); break; } Object obj = msg.obj; if (obj instanceof SomeArgs) { Loading Loading @@ -6308,6 +6322,17 @@ public final class ActivityThread { return retHolder; } private void handleRunIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) { try { Method main = Class.forName(entryPoint).getMethod("main", String[].class); main.invoke(null, new Object[]{entryPointArgs}); } catch (ReflectiveOperationException e) { throw new AndroidRuntimeException("runIsolatedEntryPoint failed", e); } // The process will be empty after this method returns; exit the VM now. System.exit(0); } private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; Loading
core/java/android/app/IApplicationThread.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ oneway interface IApplicationThread { boolean restrictedBackupMode, boolean persistent, in Configuration config, in CompatibilityInfo compatInfo, in Map services, in Bundle coreSettings, in String buildSerial); void runIsolatedEntryPoint(in String entryPoint, in String[] entryPointArgs); void scheduleExit(); void scheduleConfigurationChanged(in Configuration config); void scheduleServiceArgs(IBinder token, in ParceledListSlice args); Loading
services/core/java/com/android/server/am/ActivityManagerService.java +29 −23 Original line number Diff line number Diff line Loading @@ -3704,6 +3704,8 @@ public class ActivityManagerService extends IActivityManager.Stub return null; } app.crashHandler = crashHandler; app.isolatedEntryPoint = entryPoint; app.isolatedEntryPointArgs = entryPointArgs; checkTime(startTime, "startProcess: done creating new process record"); } else { // If this is a new package in the process, add the package to the list Loading @@ -3726,8 +3728,7 @@ public class ActivityManagerService extends IActivityManager.Stub } checkTime(startTime, "startProcess: stepping in to startProcess"); startProcessLocked( app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); startProcessLocked(app, hostingType, hostingNameStr, abiOverride); checkTime(startTime, "startProcess: done starting proc!"); return (app.pid != 0) ? app : null; } Loading @@ -3738,12 +3739,11 @@ public class ActivityManagerService extends IActivityManager.Stub private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) { startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, null /* entryPoint */, null /* entryPointArgs */); startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */); } private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { String hostingNameStr, String abiOverride) { long startTime = SystemClock.elapsedRealtime(); if (app.pid > 0 && app.pid != MY_PID) { checkTime(startTime, "startProcess: removing from pids map"); Loading Loading @@ -3888,8 +3888,7 @@ public class ActivityManagerService extends IActivityManager.Stub + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; final String entryPoint = "android.app.ActivityThread"; Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + app.processName); checkTime(startTime, "startProcess: asking zygote to start proc"); Loading @@ -3898,12 +3897,12 @@ public class ActivityManagerService extends IActivityManager.Stub startResult = startWebView(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, entryPointArgs); app.info.dataDir, null, null); } else { startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, entryPointArgs); app.info.dataDir, invokeWith, null); } checkTime(startTime, "startProcess: returned from zygote!"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Loading Loading @@ -3936,9 +3935,9 @@ public class ActivityManagerService extends IActivityManager.Stub buf.append(app.processName); buf.append('/'); UserHandle.formatUid(buf, uid); if (!isActivityProcess) { if (app.isolatedEntryPoint != null) { buf.append(" ["); buf.append(entryPoint); buf.append(app.isolatedEntryPoint); buf.append("]"); } buf.append(" for "); Loading Loading @@ -3968,13 +3967,11 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized (mPidsSelfLocked) { this.mPidsSelfLocked.put(startResult.pid, app); if (isActivityProcess) { Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); msg.obj = app; mHandler.sendMessageDelayed(msg, startResult.usingWrapper ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); } } checkTime(startTime, "startProcess: done updating pids map"); } catch (RuntimeException e) { Slog.e(TAG, "Failure starting process " + app.processName, e); Loading Loading @@ -7005,7 +7002,11 @@ public class ActivityManagerService extends IActivityManager.Stub checkTime(startTime, "attachApplicationLocked: immediately before bindApplication"); mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app); if (app.instr != null) { if (app.isolatedEntryPoint != null) { // This is an isolated process which should just call an entry point instead of // being bound to an application. thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs); } else if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, Loading Loading @@ -12249,6 +12250,11 @@ public class ActivityManagerService extends IActivityManager.Stub r.persistent = true; r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; } if (isolated && isolatedUid != 0) { // Special case for startIsolatedProcess (internal only) - assume the process // is required by the system server to prevent it being killed. r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ; } addProcessNameLocked(r); return r; } Loading Loading @@ -12316,8 +12322,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { mPersistentStartingProcesses.add(app); startProcessLocked(app, "added application", customProcess != null ? customProcess : app.processName, abiOverride, null /* entryPoint */, null /* entryPointArgs */); customProcess != null ? customProcess : app.processName, abiOverride); } return app; Loading Loading @@ -22556,9 +22561,10 @@ public class ActivityManagerService extends IActivityManager.Stub break; } if (app.isolated && app.services.size() <= 0) { // If this is an isolated process, and there are no // services running in it, then the process is no longer if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) { // If this is an isolated process, there are no services // running in it, and it's not a special process with a // custom entry point, then the process is no longer // needed. We agressively kill these because we can by // definition not re-use the same process again, and it is // good to avoid having whatever code was running in them
services/core/java/com/android/server/am/ProcessRecord.java +9 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.util.TimeUtils; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; /** * Full information about a particular process that Loading Loading @@ -174,6 +175,9 @@ final class ProcessRecord { // All ContentProviderRecord process is using final ArrayList<ContentProviderConnection> conProviders = new ArrayList<>(); String isolatedEntryPoint; // Class to run on start if this is a special isolated process. String[] isolatedEntryPointArgs; // Arguments to pass to isolatedEntryPoint's main(). boolean execServicesFg; // do we need to be executing services in the foreground? boolean persistent; // always keep this application running? boolean crashing; // are we in the process of crashing? Loading Loading @@ -379,6 +383,11 @@ final class ProcessRecord { if (whitelistManager) { pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager); } if (isolatedEntryPoint != null || isolatedEntryPointArgs != null) { pw.print(prefix); pw.print("isolatedEntryPoint="); pw.println(isolatedEntryPoint); pw.print(prefix); pw.print("isolatedEntryPointArgs="); pw.println(Arrays.toString(isolatedEntryPointArgs)); } if (activities.size() > 0) { pw.print(prefix); pw.println("Activities:"); for (int i=0; i<activities.size(); i++) { Loading