blob: c6b3e7cd639f2b3a285962e6ec6c101cf22b4636 [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;
28import libcore.io.Libcore;
29
30import dalvik.system.Zygote;
31
32/**
33 * Startup class for the wrapper process.
34 * @hide
35 */
36public class WrapperInit {
37 private final static String TAG = "AndroidRuntime";
38
39 /**
40 * Class not instantiable.
41 */
42 private WrapperInit() {
43 }
44
45 /**
46 * The main function called when starting a runtime application through a
47 * wrapper process instead of by forking Zygote.
48 *
49 * The first argument specifies the file descriptor for a pipe that should receive
Elliott Hughese1dfcb72011-07-08 11:08:07 -070050 * the pid of this process, or 0 if none.
51 *
52 * The second argument is the target SDK version for the app.
53 *
54 * The remaining arguments are passed to the runtime.
Jeff Brownebed7d62011-05-16 17:08:42 -070055 *
56 * @param args The command-line arguments.
57 */
58 public static void main(String[] args) {
59 try {
Elliott Hughese1dfcb72011-07-08 11:08:07 -070060 // Parse our mandatory arguments.
61 int fdNum = Integer.parseInt(args[0], 10);
62 int targetSdkVersion = Integer.parseInt(args[1], 10);
63
Jeff Brown0c2313d2011-06-10 22:46:40 -070064 // Tell the Zygote what our actual PID is (since it only knows about the
65 // wrapper that it directly forked).
Jeff Brownebed7d62011-05-16 17:08:42 -070066 if (fdNum != 0) {
67 try {
68 FileDescriptor fd = ZygoteInit.createFileDescriptor(fdNum);
69 DataOutputStream os = new DataOutputStream(new FileOutputStream(fd));
70 os.writeInt(Process.myPid());
71 os.close();
72 IoUtils.closeQuietly(fd);
73 } catch (IOException ex) {
74 Slog.d(TAG, "Could not write pid of wrapped process to Zygote pipe.", ex);
75 }
76 }
77
Jeff Brown0c2313d2011-06-10 22:46:40 -070078 // Mimic Zygote preloading.
79 ZygoteInit.preload();
80
81 // Launch the application.
Elliott Hughese1dfcb72011-07-08 11:08:07 -070082 String[] runtimeArgs = new String[args.length - 2];
83 System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
84 RuntimeInit.wrapperInit(targetSdkVersion, runtimeArgs);
Jeff Brownebed7d62011-05-16 17:08:42 -070085 } catch (ZygoteInit.MethodAndArgsCaller caller) {
86 caller.run();
87 }
88 }
89
90 /**
91 * Executes a runtime application with a wrapper command.
92 * This method never returns.
93 *
94 * @param invokeWith The wrapper command.
95 * @param niceName The nice name for the application, or null if none.
Elliott Hughese1dfcb72011-07-08 11:08:07 -070096 * @param targetSdkVersion The target SDK version for the app.
Jeff Brownebed7d62011-05-16 17:08:42 -070097 * @param pipeFd The pipe to which the application's pid should be written, or null if none.
98 * @param args Arguments for {@link RuntimeInit.main}.
99 */
100 public static void execApplication(String invokeWith, String niceName,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700101 int targetSdkVersion, FileDescriptor pipeFd, String[] args) {
Jeff Brownebed7d62011-05-16 17:08:42 -0700102 StringBuilder command = new StringBuilder(invokeWith);
103 command.append(" /system/bin/app_process /system/bin --application");
104 if (niceName != null) {
105 command.append(" '--nice-name=").append(niceName).append("'");
106 }
107 command.append(" com.android.internal.os.WrapperInit ");
108 command.append(pipeFd != null ? pipeFd.getInt$() : 0);
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700109 command.append(' ');
110 command.append(targetSdkVersion);
Jeff Brownebed7d62011-05-16 17:08:42 -0700111 Zygote.appendQuotedShellArgs(command, args);
112 Zygote.execShell(command.toString());
113 }
114
115 /**
116 * Executes a standalone application with a wrapper command.
117 * This method never returns.
118 *
119 * @param invokeWith The wrapper command.
120 * @param classPath The class path.
121 * @param className The class name to invoke.
122 * @param args Arguments for the main() method of the specified class.
123 */
124 public static void execStandalone(String invokeWith, String classPath, String className,
125 String[] args) {
126 StringBuilder command = new StringBuilder(invokeWith);
127 command.append(" /system/bin/dalvikvm -classpath '").append(classPath);
128 command.append("' ").append(className);
129 Zygote.appendQuotedShellArgs(command, args);
130 Zygote.execShell(command.toString());
131 }
132}