• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.internal.os;
18 
19 import android.os.Process;
20 import android.util.Slog;
21 
22 import java.io.DataOutputStream;
23 import java.io.FileDescriptor;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 
27 import libcore.io.IoUtils;
28 import libcore.io.Libcore;
29 
30 import dalvik.system.Zygote;
31 
32 /**
33  * Startup class for the wrapper process.
34  * @hide
35  */
36 public class WrapperInit {
37     private final static String TAG = "AndroidRuntime";
38 
39     /**
40      * Class not instantiable.
41      */
WrapperInit()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
50      * 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.
55      *
56      * @param args The command-line arguments.
57      */
main(String[] args)58     public static void main(String[] args) {
59         try {
60             // Parse our mandatory arguments.
61             int fdNum = Integer.parseInt(args[0], 10);
62             int targetSdkVersion = Integer.parseInt(args[1], 10);
63 
64             // Tell the Zygote what our actual PID is (since it only knows about the
65             // wrapper that it directly forked).
66             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 
78             // Mimic Zygote preloading.
79             ZygoteInit.preload();
80 
81             // Launch the application.
82             String[] runtimeArgs = new String[args.length - 2];
83             System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
84             RuntimeInit.wrapperInit(targetSdkVersion, runtimeArgs);
85         } 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.
96      * @param targetSdkVersion The target SDK version for the app.
97      * @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      */
execApplication(String invokeWith, String niceName, int targetSdkVersion, FileDescriptor pipeFd, String[] args)100     public static void execApplication(String invokeWith, String niceName,
101             int targetSdkVersion, FileDescriptor pipeFd, String[] args) {
102         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);
109         command.append(' ');
110         command.append(targetSdkVersion);
111         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      */
execStandalone(String invokeWith, String classPath, String className, String[] args)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 }
133