blob: 1766f7b1743b47b4bcaf2665af0ec4c7a27f6838 [file] [log] [blame]
Jeff Brownebed7d62011-05-16 17:08:42 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
19import android.os.Process;
20import android.util.Slog;
21
22import java.io.DataOutputStream;
23import java.io.FileDescriptor;
24import java.io.FileOutputStream;
25import java.io.IOException;
26
27import libcore.io.IoUtils;
Jeff Brownebed7d62011-05-16 17:08:42 -070028
29import dalvik.system.Zygote;
30
31/**
32 * Startup class for the wrapper process.
33 * @hide
34 */
35public class WrapperInit {
36 private final static String TAG = "AndroidRuntime";
37
38 /**
39 * Class not instantiable.
40 */
41 private WrapperInit() {
42 }
43
44 /**
45 * The main function called when starting a runtime application through a
46 * wrapper process instead of by forking Zygote.
47 *
48 * The first argument specifies the file descriptor for a pipe that should receive
Elliott Hughese1dfcb72011-07-08 11:08:07 -070049 * the pid of this process, or 0 if none.
50 *
51 * The second argument is the target SDK version for the app.
52 *
53 * The remaining arguments are passed to the runtime.
Jeff Brownebed7d62011-05-16 17:08:42 -070054 *
55 * @param args The command-line arguments.
56 */
57 public static void main(String[] args) {
58 try {
Elliott Hughese1dfcb72011-07-08 11:08:07 -070059 // Parse our mandatory arguments.
60 int fdNum = Integer.parseInt(args[0], 10);
61 int targetSdkVersion = Integer.parseInt(args[1], 10);
62
Jeff Brown0c2313d2011-06-10 22:46:40 -070063 // Tell the Zygote what our actual PID is (since it only knows about the
64 // wrapper that it directly forked).
Jeff Brownebed7d62011-05-16 17:08:42 -070065 if (fdNum != 0) {
66 try {
67 FileDescriptor fd = ZygoteInit.createFileDescriptor(fdNum);
68 DataOutputStream os = new DataOutputStream(new FileOutputStream(fd));
69 os.writeInt(Process.myPid());
70 os.close();
71 IoUtils.closeQuietly(fd);
72 } catch (IOException ex) {
73 Slog.d(TAG, "Could not write pid of wrapped process to Zygote pipe.", ex);
74 }
75 }
76
Jeff Brown0c2313d2011-06-10 22:46:40 -070077 // Mimic Zygote preloading.
78 ZygoteInit.preload();
79
80 // Launch the application.
Elliott Hughese1dfcb72011-07-08 11:08:07 -070081 String[] runtimeArgs = new String[args.length - 2];
82 System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
83 RuntimeInit.wrapperInit(targetSdkVersion, runtimeArgs);
Jeff Brownebed7d62011-05-16 17:08:42 -070084 } catch (ZygoteInit.MethodAndArgsCaller caller) {
85 caller.run();
86 }
87 }
88
89 /**
90 * Executes a runtime application with a wrapper command.
91 * This method never returns.
92 *
93 * @param invokeWith The wrapper command.
94 * @param niceName The nice name for the application, or null if none.
Elliott Hughese1dfcb72011-07-08 11:08:07 -070095 * @param targetSdkVersion The target SDK version for the app.
Jeff Brownebed7d62011-05-16 17:08:42 -070096 * @param pipeFd The pipe to which the application's pid should be written, or null if none.
97 * @param args Arguments for {@link RuntimeInit.main}.
98 */
99 public static void execApplication(String invokeWith, String niceName,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700100 int targetSdkVersion, FileDescriptor pipeFd, String[] args) {
Jeff Brownebed7d62011-05-16 17:08:42 -0700101 StringBuilder command = new StringBuilder(invokeWith);
102 command.append(" /system/bin/app_process /system/bin --application");
103 if (niceName != null) {
104 command.append(" '--nice-name=").append(niceName).append("'");
105 }
106 command.append(" com.android.internal.os.WrapperInit ");
107 command.append(pipeFd != null ? pipeFd.getInt$() : 0);
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700108 command.append(' ');
109 command.append(targetSdkVersion);
Jeff Brownebed7d62011-05-16 17:08:42 -0700110 Zygote.appendQuotedShellArgs(command, args);
111 Zygote.execShell(command.toString());
112 }
113
114 /**
115 * Executes a standalone application with a wrapper command.
116 * This method never returns.
117 *
118 * @param invokeWith The wrapper command.
119 * @param classPath The class path.
120 * @param className The class name to invoke.
121 * @param args Arguments for the main() method of the specified class.
122 */
123 public static void execStandalone(String invokeWith, String classPath, String className,
124 String[] args) {
125 StringBuilder command = new StringBuilder(invokeWith);
126 command.append(" /system/bin/dalvikvm -classpath '").append(classPath);
127 command.append("' ").append(className);
128 Zygote.appendQuotedShellArgs(command, args);
129 Zygote.execShell(command.toString());
130 }
131}