Home | History | Annotate | Download | only in os
      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      */
     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      */
     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      */
     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     /**
    126      * Executes a standalone application with a wrapper command.
    127      * This method never returns.
    128      *
    129      * @param invokeWith The wrapper command.
    130      * @param classPath The class path.
    131      * @param className The class name to invoke.
    132      * @param args Arguments for the main() method of the specified class.
    133      */
    134     public static void execStandalone(String invokeWith, String classPath, String className,
    135             String[] args) {
    136         StringBuilder command = new StringBuilder(invokeWith);
    137         command.append(" /system/bin/dalvikvm -classpath '").append(classPath);
    138         command.append("' ").append(className);
    139         Zygote.appendQuotedShellArgs(command, args);
    140         Zygote.execShell(command.toString());
    141     }
    142 }
    143