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