WrapperInit.java revision 6090995951c6e2e4dcf38102f01793f8a94166e1
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 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; 28 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 49 * 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. 54 * 55 * @param args The command-line arguments. 56 */ 57 public static void main(String[] args) { 58 try { 59 // Parse our mandatory arguments. 60 int fdNum = Integer.parseInt(args[0], 10); 61 int targetSdkVersion = Integer.parseInt(args[1], 10); 62 63 // Tell the Zygote what our actual PID is (since it only knows about the 64 // wrapper that it directly forked). 65 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 77 // Mimic Zygote preloading. 78 ZygoteInit.preload(); 79 80 // Launch the application. 81 String[] runtimeArgs = new String[args.length - 2]; 82 System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length); 83 RuntimeInit.wrapperInit(targetSdkVersion, runtimeArgs); 84 } 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. 95 * @param targetSdkVersion The target SDK version for the app. 96 * @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, 100 int targetSdkVersion, FileDescriptor pipeFd, String[] args) { 101 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); 108 command.append(' '); 109 command.append(targetSdkVersion); 110 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} 132