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 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      */
     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      */
     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      */
     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      */
    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