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 dalvik.system.VMRuntime; 23 import java.io.DataOutputStream; 24 import java.io.FileDescriptor; 25 import java.io.FileOutputStream; 26 import java.io.IOException; 27 28 import libcore.io.IoUtils; 29 30 /** 31 * Startup class for the wrapper process. 32 * @hide 33 */ 34 public class WrapperInit { 35 private final static String TAG = "AndroidRuntime"; 36 37 /** 38 * Class not instantiable. 39 */ WrapperInit()40 private WrapperInit() { 41 } 42 43 /** 44 * The main function called when starting a runtime application through a 45 * wrapper process instead of by forking Zygote. 46 * 47 * The first argument specifies the file descriptor for a pipe that should receive 48 * the pid of this process, or 0 if none. 49 * 50 * The second argument is the target SDK version for the app. 51 * 52 * The remaining arguments are passed to the runtime. 53 * 54 * @param args The command-line arguments. 55 */ main(String[] args)56 public static void main(String[] args) { 57 try { 58 // Parse our mandatory arguments. 59 int fdNum = Integer.parseInt(args[0], 10); 60 int targetSdkVersion = Integer.parseInt(args[1], 10); 61 62 // Tell the Zygote what our actual PID is (since it only knows about the 63 // wrapper that it directly forked). 64 if (fdNum != 0) { 65 try { 66 FileDescriptor fd = new FileDescriptor(); 67 fd.setInt$(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 */ execApplication(String invokeWith, String niceName, int targetSdkVersion, String instructionSet, FileDescriptor pipeFd, String[] args)99 public static void execApplication(String invokeWith, String niceName, 100 int targetSdkVersion, String instructionSet, FileDescriptor pipeFd, 101 String[] args) { 102 StringBuilder command = new StringBuilder(invokeWith); 103 104 final String appProcess; 105 if (VMRuntime.is64BitInstructionSet(instructionSet)) { 106 appProcess = "/system/bin/app_process64"; 107 } else { 108 appProcess = "/system/bin/app_process32"; 109 } 110 command.append(' '); 111 command.append(appProcess); 112 113 command.append(" /system/bin --application"); 114 if (niceName != null) { 115 command.append(" '--nice-name=").append(niceName).append("'"); 116 } 117 command.append(" com.android.internal.os.WrapperInit "); 118 command.append(pipeFd != null ? pipeFd.getInt$() : 0); 119 command.append(' '); 120 command.append(targetSdkVersion); 121 Zygote.appendQuotedShellArgs(command, args); 122 Zygote.execShell(command.toString()); 123 } 124 } 125