summaryrefslogtreecommitdiffstats
path: root/core/java/com/android/internal/os
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/com/android/internal/os')
-rwxr-xr-xcore/java/com/android/internal/os/PkgUsageStats.java22
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java13
-rw-r--r--core/java/com/android/internal/os/WrapperInit.java23
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java22
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java11
5 files changed, 71 insertions, 20 deletions
diff --git a/core/java/com/android/internal/os/PkgUsageStats.java b/core/java/com/android/internal/os/PkgUsageStats.java
index 1ac191b..8c2c405 100755
--- a/core/java/com/android/internal/os/PkgUsageStats.java
+++ b/core/java/com/android/internal/os/PkgUsageStats.java
@@ -19,6 +19,9 @@ package com.android.internal.os;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* implementation of PkgUsageStats associated with an
* application package.
@@ -28,6 +31,7 @@ public class PkgUsageStats implements Parcelable {
public String packageName;
public int launchCount;
public long usageTime;
+ public Map<String, Long> componentResumeTimes;
public static final Parcelable.Creator<PkgUsageStats> CREATOR
= new Parcelable.Creator<PkgUsageStats>() {
@@ -46,31 +50,45 @@ public class PkgUsageStats implements Parcelable {
+ " " + packageName + "}";
}
- public PkgUsageStats(String pkgName, int count, long time) {
+ public PkgUsageStats(String pkgName, int count, long time, Map<String, Long> lastResumeTimes) {
packageName = pkgName;
launchCount = count;
usageTime = time;
+ componentResumeTimes = new HashMap<String, Long>(lastResumeTimes);
}
public PkgUsageStats(Parcel source) {
packageName = source.readString();
launchCount = source.readInt();
usageTime = source.readLong();
+ final int N = source.readInt();
+ componentResumeTimes = new HashMap<String, Long>(N);
+ for (int i = 0; i < N; i++) {
+ String component = source.readString();
+ long lastResumeTime = source.readLong();
+ componentResumeTimes.put(component, lastResumeTime);
+ }
}
public PkgUsageStats(PkgUsageStats pStats) {
packageName = pStats.packageName;
launchCount = pStats.launchCount;
usageTime = pStats.usageTime;
+ componentResumeTimes = new HashMap<String, Long>(pStats.componentResumeTimes);
}
public int describeContents() {
return 0;
}
- public void writeToParcel(Parcel dest, int parcelableFlags){
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
dest.writeString(packageName);
dest.writeInt(launchCount);
dest.writeLong(usageTime);
+ dest.writeInt(componentResumeTimes.size());
+ for (Map.Entry<String, Long> ent : componentResumeTimes.entrySet()) {
+ dest.writeString(ent.getKey());
+ dest.writeLong(ent.getValue());
+ }
}
}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index f13e770..53516c0 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -252,9 +252,10 @@ public class RuntimeInit {
* <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
* </ul>
*
+ * @param targetSdkVersion target SDK version
* @param argv arg strings
*/
- public static final void zygoteInit(String[] argv)
+ public static final void zygoteInit(int targetSdkVersion, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
@@ -263,7 +264,7 @@ public class RuntimeInit {
commonInit();
zygoteInitNative();
- applicationInit(argv);
+ applicationInit(targetSdkVersion, argv);
}
/**
@@ -274,20 +275,22 @@ public class RuntimeInit {
* which calls {@link WrapperInit#main} which then calls this method.
* So we don't need to call commonInit() here.
*
+ * @param targetSdkVersion target SDK version
* @param argv arg strings
*/
- public static void wrapperInit(String[] argv)
+ public static void wrapperInit(int targetSdkVersion, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from wrapper");
- applicationInit(argv);
+ applicationInit(targetSdkVersion, argv);
}
- private static void applicationInit(String[] argv)
+ private static void applicationInit(int targetSdkVersion, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
+ VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index 860a08c..c6b3e7c 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -47,16 +47,22 @@ public class WrapperInit {
* wrapper process instead of by forking Zygote.
*
* The first argument specifies the file descriptor for a pipe that should receive
- * the pid of this process, or 0 if none. The remaining arguments are passed to
- * the runtime.
+ * the pid of this process, or 0 if none.
+ *
+ * The second argument is the target SDK version for the app.
+ *
+ * The remaining arguments are passed to the runtime.
*
* @param args The command-line arguments.
*/
public static void main(String[] args) {
try {
+ // Parse our mandatory arguments.
+ int fdNum = Integer.parseInt(args[0], 10);
+ int targetSdkVersion = Integer.parseInt(args[1], 10);
+
// Tell the Zygote what our actual PID is (since it only knows about the
// wrapper that it directly forked).
- int fdNum = Integer.parseInt(args[0], 10);
if (fdNum != 0) {
try {
FileDescriptor fd = ZygoteInit.createFileDescriptor(fdNum);
@@ -73,9 +79,9 @@ public class WrapperInit {
ZygoteInit.preload();
// Launch the application.
- String[] runtimeArgs = new String[args.length - 1];
- System.arraycopy(args, 1, runtimeArgs, 0, runtimeArgs.length);
- RuntimeInit.wrapperInit(runtimeArgs);
+ String[] runtimeArgs = new String[args.length - 2];
+ System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
+ RuntimeInit.wrapperInit(targetSdkVersion, runtimeArgs);
} catch (ZygoteInit.MethodAndArgsCaller caller) {
caller.run();
}
@@ -87,11 +93,12 @@ public class WrapperInit {
*
* @param invokeWith The wrapper command.
* @param niceName The nice name for the application, or null if none.
+ * @param targetSdkVersion The target SDK version for the app.
* @param pipeFd The pipe to which the application's pid should be written, or null if none.
* @param args Arguments for {@link RuntimeInit.main}.
*/
public static void execApplication(String invokeWith, String niceName,
- FileDescriptor pipeFd, String[] args) {
+ int targetSdkVersion, FileDescriptor pipeFd, String[] args) {
StringBuilder command = new StringBuilder(invokeWith);
command.append(" /system/bin/app_process /system/bin --application");
if (niceName != null) {
@@ -99,6 +106,8 @@ public class WrapperInit {
}
command.append(" com.android.internal.os.WrapperInit ");
command.append(pipeFd != null ? pipeFd.getInt$() : 0);
+ command.append(' ');
+ command.append(targetSdkVersion);
Zygote.appendQuotedShellArgs(command, args);
Zygote.execShell(command.toString());
}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 7cb002c..9af7e96 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -18,6 +18,7 @@ package com.android.internal.os;
import android.net.Credentials;
import android.net.LocalSocket;
+import android.os.Build;
import android.os.Process;
import android.os.SystemProperties;
import android.util.Log;
@@ -333,6 +334,10 @@ class ZygoteConnection {
*/
int debugFlags;
+ /** from --target-sdk-version. */
+ int targetSdkVersion;
+ boolean targetSdkVersionSpecified;
+
/** from --classpath */
String classpath;
@@ -402,6 +407,14 @@ class ZygoteConnection {
gidSpecified = true;
gid = Integer.parseInt(
arg.substring(arg.indexOf('=') + 1));
+ } else if (arg.startsWith("--target-sdk-version=")) {
+ if (targetSdkVersionSpecified) {
+ throw new IllegalArgumentException(
+ "Duplicate target-sdk-version specified");
+ }
+ targetSdkVersionSpecified = true;
+ targetSdkVersion = Integer.parseInt(
+ arg.substring(arg.indexOf('=') + 1));
} else if (arg.equals("--enable-debugger")) {
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
} else if (arg.equals("--enable-safemode")) {
@@ -821,9 +834,11 @@ class ZygoteConnection {
if (parsedArgs.runtimeInit) {
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
- parsedArgs.niceName, pipeFd, parsedArgs.remainingArgs);
+ parsedArgs.niceName, parsedArgs.targetSdkVersion,
+ pipeFd, parsedArgs.remainingArgs);
} else {
- RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
+ RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
+ parsedArgs.remainingArgs);
}
} else {
String className;
@@ -885,6 +900,7 @@ class ZygoteConnection {
}
}
+ boolean usingWrapper = false;
if (pipeFd != null && pid > 0) {
DataInputStream is = new DataInputStream(new FileInputStream(pipeFd));
int innerPid = -1;
@@ -909,6 +925,7 @@ class ZygoteConnection {
if (parentPid > 0) {
Log.i(TAG, "Wrapped process has pid " + innerPid);
pid = innerPid;
+ usingWrapper = true;
} else {
Log.w(TAG, "Wrapped process reported a pid that is not a child of "
+ "the process that we forked: childPid=" + pid
@@ -919,6 +936,7 @@ class ZygoteConnection {
try {
mSocketOutStream.writeInt(pid);
+ mSocketOutStream.writeBoolean(usingWrapper);
} catch (IOException ex) {
Log.e(TAG, "Error reading from command socket", ex);
return true;
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index b4a7e52..6ec186d 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -48,7 +48,7 @@ import java.util.ArrayList;
* Startup class for the zygote process.
*
* Pre-initializes some classes, and then waits for commands on a UNIX domain
- * socket. Based on these commands, forks of child processes that inherit
+ * socket. Based on these commands, forks off child processes that inherit
* the initial state of the VM.
*
* Please see {@link ZygoteConnection.Arguments} for documentation on the
@@ -453,12 +453,13 @@ public class ZygoteInit {
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
- parsedArgs.niceName, null, parsedArgs.remainingArgs);
+ parsedArgs.niceName, parsedArgs.targetSdkVersion,
+ null, parsedArgs.remainingArgs);
} else {
/*
* Pass the remaining arguments to SystemServer.
*/
- RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
+ RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
}
/* should never reach here */
@@ -491,7 +492,9 @@ public class ZygoteInit {
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, null,
+ parsedArgs.gids,
+ parsedArgs.debugFlags,
+ null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {