• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Main entry of app process.
3  *
4  * Starts the interpreted runtime, then starts up the application.
5  *
6  */
7 
8 #define LOG_TAG "appproc"
9 
10 #include <binder/IPCThreadState.h>
11 #include <binder/ProcessState.h>
12 #include <utils/Log.h>
13 #include <cutils/process_name.h>
14 #include <cutils/memory.h>
15 #include <android_runtime/AndroidRuntime.h>
16 
17 #include <stdio.h>
18 #include <unistd.h>
19 
20 namespace android {
21 
app_usage()22 void app_usage()
23 {
24     fprintf(stderr,
25         "Usage: app_process [java-options] cmd-dir start-class-name [options]\n");
26 }
27 
app_init(const char * className,int argc,const char * const argv[])28 status_t app_init(const char* className, int argc, const char* const argv[])
29 {
30     LOGV("Entered app_init()!\n");
31 
32     AndroidRuntime* jr = AndroidRuntime::getRuntime();
33     jr->callMain(className, argc, argv);
34 
35     LOGV("Exiting app_init()!\n");
36     return NO_ERROR;
37 }
38 
39 class AppRuntime : public AndroidRuntime
40 {
41 public:
AppRuntime()42     AppRuntime()
43         : mParentDir(NULL)
44         , mClassName(NULL)
45         , mArgC(0)
46         , mArgV(NULL)
47     {
48     }
49 
50 #if 0
51     // this appears to be unused
52     const char* getParentDir() const
53     {
54         return mParentDir;
55     }
56 #endif
57 
getClassName() const58     const char* getClassName() const
59     {
60         return mClassName;
61     }
62 
onStarted()63     virtual void onStarted()
64     {
65         sp<ProcessState> proc = ProcessState::self();
66         if (proc->supportsProcesses()) {
67             LOGV("App process: starting thread pool.\n");
68             proc->startThreadPool();
69         }
70 
71         app_init(mClassName, mArgC, mArgV);
72 
73         if (ProcessState::self()->supportsProcesses()) {
74             IPCThreadState::self()->stopProcess();
75         }
76     }
77 
onZygoteInit()78     virtual void onZygoteInit()
79     {
80         sp<ProcessState> proc = ProcessState::self();
81         if (proc->supportsProcesses()) {
82             LOGV("App process: starting thread pool.\n");
83             proc->startThreadPool();
84         }
85     }
86 
onExit(int code)87     virtual void onExit(int code)
88     {
89         if (mClassName == NULL) {
90             // if zygote
91             if (ProcessState::self()->supportsProcesses()) {
92                 IPCThreadState::self()->stopProcess();
93             }
94         }
95 
96         AndroidRuntime::onExit(code);
97     }
98 
99 
100     const char* mParentDir;
101     const char* mClassName;
102     int mArgC;
103     const char* const* mArgV;
104 };
105 
106 }
107 
108 using namespace android;
109 
110 /*
111  * sets argv0 to as much of newArgv0 as will fit
112  */
setArgv0(const char * argv0,const char * newArgv0)113 static void setArgv0(const char *argv0, const char *newArgv0)
114 {
115     strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0));
116 }
117 
main(int argc,const char * const argv[])118 int main(int argc, const char* const argv[])
119 {
120     // These are global variables in ProcessState.cpp
121     mArgC = argc;
122     mArgV = argv;
123 
124     mArgLen = 0;
125     for (int i=0; i<argc; i++) {
126         mArgLen += strlen(argv[i]) + 1;
127     }
128     mArgLen--;
129 
130     AppRuntime runtime;
131     const char *arg;
132     const char *argv0;
133 
134     argv0 = argv[0];
135 
136     // Process command line arguments
137     // ignore argv[0]
138     argc--;
139     argv++;
140 
141     // Everything up to '--' or first non '-' arg goes to the vm
142 
143     int i = runtime.addVmArguments(argc, argv);
144 
145     // Next arg is parent directory
146     if (i < argc) {
147         runtime.mParentDir = argv[i++];
148     }
149 
150     // Next arg is startup classname or "--zygote"
151     if (i < argc) {
152         arg = argv[i++];
153         if (0 == strcmp("--zygote", arg)) {
154             bool startSystemServer = (i < argc) ?
155                     strcmp(argv[i], "--start-system-server") == 0 : false;
156             setArgv0(argv0, "zygote");
157             set_process_name("zygote");
158             runtime.start("com.android.internal.os.ZygoteInit",
159                 startSystemServer);
160         } else {
161             set_process_name(argv0);
162 
163             runtime.mClassName = arg;
164 
165             // Remainder of args get passed to startup class main()
166             runtime.mArgC = argc-i;
167             runtime.mArgV = argv+i;
168 
169             LOGV("App process is starting with pid=%d, class=%s.\n",
170                  getpid(), runtime.getClassName());
171             runtime.start();
172         }
173     } else {
174         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
175         fprintf(stderr, "Error: no class name or --zygote supplied.\n");
176         app_usage();
177         return 10;
178     }
179 
180 }
181