AndroidRuntime.cpp revision 1194e754a95e1fa5d4eba6d0bca109156dd4df94
14c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn/*
24c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Copyright (C) 2006 The Android Open Source Project
34c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn *
44c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
54c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * you may not use this file except in compliance with the License.
64c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * You may obtain a copy of the License at
74c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn *
84c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
94c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn *
104c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * See the License for the specific language governing permissions and
144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * limitations under the License.
154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn */
164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
17ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn#define LOG_TAG "AndroidRuntime"
184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn//#define LOG_NDEBUG 0
19de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlock
20c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson#include <android_runtime/AndroidRuntime.h>
21de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlock#include <binder/IBinder.h>
22de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlock#include <binder/IPCThreadState.h>
23407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy#include <binder/IServiceManager.h>
244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn#include <utils/Log.h>
25c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase#include <utils/misc.h>
26407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy#include <binder/Parcel.h>
274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn#include <utils/threads.h>
28759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn#include <cutils/properties.h>
29824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka
30e2d034c9014919a45ddd717d4e564e73771b2fefMathias Agopian#include <SkGraphics.h>
31407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy#include <SkImageDecoder.h>
327e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos
33043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy#include "jni.h"
34c5887ea7a0b82cc5909743ce14cbda1dcf1dfc82Jorim Jaggi#include "JNIHelp.h"
35407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy#include "JniInvocation.h"
364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn#include "android_util_Binder.h"
37c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn
38824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka#include <stdio.h>
399b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos#include <signal.h>
408df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn#include <sys/stat.h>
414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn#include <sys/types.h>
422f20081f9fd734e466147bf1091d06cc7331458cChet Haase#include <signal.h>
43407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy#include <dirent.h>
44ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos#include <assert.h>
45407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
46ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos
47407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyusing namespace android;
48407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
49407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_Binder(JNIEnv* env);
50407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_Process(JNIEnv* env);
51de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockextern int register_android_graphics_Bitmap(JNIEnv*);
52de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockextern int register_android_graphics_BitmapFactory(JNIEnv*);
53de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockextern int register_android_graphics_BitmapRegionDecoder(JNIEnv*);
54de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockextern int register_android_graphics_Camera(JNIEnv* env);
55de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockextern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env);
564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornextern int register_android_graphics_Graphics(JNIEnv* env);
574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornextern int register_android_graphics_Interpolator(JNIEnv* env);
584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornextern int register_android_graphics_MaskFilter(JNIEnv* env);
594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornextern int register_android_graphics_Movie(JNIEnv* env);
60407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_graphics_NinePatch(JNIEnv*);
614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornextern int register_android_graphics_PathEffect(JNIEnv* env);
62fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brownextern int register_android_graphics_Shader(JNIEnv* env);
63407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_graphics_Typeface(JNIEnv* env);
64fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brownextern int register_android_graphics_YuvImage(JNIEnv* env);
65043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy
66fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brownextern int register_com_google_android_gles_jni_EGLImpl(JNIEnv* env);
67ba39839444532af0ed3766f736582413f6d7a40bDianne Hackbornextern int register_com_google_android_gles_jni_GLImpl(JNIEnv* env);
68881fb2092b41f4447e708da2f341d2ca5602c0d4Erik Gillingextern int register_android_opengl_jni_EGL14(JNIEnv* env);
69ba39839444532af0ed3766f736582413f6d7a40bDianne Hackbornextern int register_android_opengl_jni_EGLExt(JNIEnv* env);
70ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_opengl_jni_GLES10(JNIEnv* env);
71407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_opengl_jni_GLES10Ext(JNIEnv* env);
72c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_opengl_jni_GLES11(JNIEnv* env);
73c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_opengl_jni_GLES11Ext(JNIEnv* env);
74407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_opengl_jni_GLES20(JNIEnv* env);
75ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_opengl_jni_GLES30(JNIEnv* env);
76ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_opengl_jni_GLES31(JNIEnv* env);
77ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_opengl_jni_GLES31Ext(JNIEnv* env);
78ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy
79ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_hardware_Camera(JNIEnv *env);
80407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_hardware_camera2_CameraMetadata(JNIEnv *env);
81407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv *env);
82407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_hardware_camera2_legacy_PerfMeasurement(JNIEnv *env);
83043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guyextern int register_android_hardware_camera2_DngCreator(JNIEnv *env);
8498365d7663cbd82979a5700faf0050220b01084dJeff Brownextern int register_android_hardware_SensorManager(JNIEnv *env);
85043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guyextern int register_android_hardware_SerialPort(JNIEnv *env);
86407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_hardware_SoundTrigger(JNIEnv *env);
87ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_hardware_UsbDevice(JNIEnv *env);
88ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_hardware_UsbDeviceConnection(JNIEnv *env);
89c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_hardware_UsbRequest(JNIEnv *env);
90c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_hardware_location_ActivityRecognitionHardware(JNIEnv* env);
91c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase
92c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_media_AudioRecord(JNIEnv *env);
93c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_media_AudioSystem(JNIEnv *env);
94c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_media_AudioTrack(JNIEnv *env);
95c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_media_JetPlayer(JNIEnv *env);
96043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guyextern int register_android_media_ToneGenerator(JNIEnv *env);
97043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy
98043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guynamespace android {
99043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy
100b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner/*
101ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy * JNI-based registration functions.  Note these are properly contained in
102c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase * namespace android.
103c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase */
104ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_content_AssetManager(JNIEnv* env);
105ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_util_EventLog(JNIEnv* env);
106ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guyextern int register_android_util_Log(JNIEnv* env);
107407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_content_StringBlock(JNIEnv* env);
108407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_content_XmlBlock(JNIEnv* env);
109407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_emoji_EmojiFactory(JNIEnv* env);
110407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_graphics_Canvas(JNIEnv* env);
111824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurkaextern int register_android_graphics_CanvasProperty(JNIEnv* env);
1125f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haaseextern int register_android_graphics_ColorFilter(JNIEnv* env);
1132f20081f9fd734e466147bf1091d06cc7331458cChet Haaseextern int register_android_graphics_DrawFilter(JNIEnv* env);
114824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurkaextern int register_android_graphics_FontFamily(JNIEnv* env);
115824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurkaextern int register_android_graphics_LayerRasterizer(JNIEnv*);
116824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurkaextern int register_android_graphics_Matrix(JNIEnv* env);
117759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackbornextern int register_android_graphics_Paint(JNIEnv* env);
1189b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roosextern int register_android_graphics_Path(JNIEnv* env);
1199b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roosextern int register_android_graphics_PathMeasure(JNIEnv* env);
1209b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roosextern int register_android_graphics_Picture(JNIEnv*);
121fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brownextern int register_android_graphics_PorterDuff(JNIEnv* env);
122fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brownextern int register_android_graphics_Rasterizer(JNIEnv* env);
123fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brownextern int register_android_graphics_Region(JNIEnv* env);
124fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brownextern int register_android_graphics_SurfaceTexture(JNIEnv* env);
125fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brownextern int register_android_graphics_Xfermode(JNIEnv* env);
126407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
127407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
128407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
129407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_DisplayEventReceiver(JNIEnv* env);
130407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_RenderNode(JNIEnv* env);
131407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_RenderNodeAnimator(JNIEnv* env);
132407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_GraphicBuffer(JNIEnv* env);
133407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_GLES20Canvas(JNIEnv* env);
134407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_HardwareLayer(JNIEnv* env);
135407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_ThreadedRenderer(JNIEnv* env);
136407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_Surface(JNIEnv* env);
137407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_SurfaceControl(JNIEnv* env);
138407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_SurfaceSession(JNIEnv* env);
139407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_view_TextureView(JNIEnv* env);
140407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
141407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_database_CursorWindow(JNIEnv* env);
142407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_database_SQLiteConnection(JNIEnv* env);
143407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_database_SQLiteGlobal(JNIEnv* env);
144407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_database_SQLiteDebug(JNIEnv* env);
145407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_nio_utils(JNIEnv* env);
146407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_Debug(JNIEnv* env);
147407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_MessageQueue(JNIEnv* env);
148209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlockextern int register_android_os_Parcel(JNIEnv* env);
149407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_SELinux(JNIEnv* env);
150407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_SystemProperties(JNIEnv *env);
151407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_SystemClock(JNIEnv* env);
152407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_Trace(JNIEnv* env);
153407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyextern int register_android_os_FileObserver(JNIEnv *env);
154ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roosextern int register_android_os_UEventObserver(JNIEnv* env);
155ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roosextern int register_android_os_MemoryFile(JNIEnv* env);
156ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roosextern int register_android_net_LocalSocketImpl(JNIEnv* env);
157ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roosextern int register_android_net_NetworkUtils(JNIEnv* env);
15830a7dfa329e79bab20f3b85dd376f736ebc6292dAdrian Roosextern int register_android_net_TrafficStats(JNIEnv* env);
15930a7dfa329e79bab20f3b85dd376f736ebc6292dAdrian Roosextern int register_android_text_AndroidCharacter(JNIEnv *env);
1607e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roosextern int register_android_text_StaticLayout(JNIEnv *env);
1617e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roosextern int register_android_text_AndroidBidi(JNIEnv *env);
16253560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roosextern int register_android_opengl_classes(JNIEnv *env);
16330a7dfa329e79bab20f3b85dd376f736ebc6292dAdrian Roosextern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
16435be7560300a97fc3675bdd325910f28827d9508Jeff Sharkeyextern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env);
16535be7560300a97fc3675bdd325910f28827d9508Jeff Sharkeyextern int register_android_backup_BackupDataInput(JNIEnv *env);
16635be7560300a97fc3675bdd325910f28827d9508Jeff Sharkeyextern int register_android_backup_BackupDataOutput(JNIEnv *env);
16735be7560300a97fc3675bdd325910f28827d9508Jeff Sharkeyextern int register_android_backup_FileBackupHelperBase(JNIEnv *env);
16835be7560300a97fc3675bdd325910f28827d9508Jeff Sharkeyextern int register_android_backup_BackupHelperDispatcher(JNIEnv *env);
169c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_app_backup_FullBackup(JNIEnv *env);
170ed0e1a68a437979e399724ca17f422add80bd0e4Jorim Jaggiextern int register_android_app_ActivityThread(JNIEnv *env);
171ed0e1a68a437979e399724ca17f422add80bd0e4Jorim Jaggiextern int register_android_app_NativeActivity(JNIEnv *env);
172ed0e1a68a437979e399724ca17f422add80bd0e4Jorim Jaggiextern int register_android_media_RemoteDisplay(JNIEnv *env);
1735f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haaseextern int register_android_view_InputChannel(JNIEnv* env);
1745f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haaseextern int register_android_view_InputDevice(JNIEnv* env);
1755f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haaseextern int register_android_view_InputEventReceiver(JNIEnv* env);
176c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_view_InputEventSender(JNIEnv* env);
177c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_view_InputQueue(JNIEnv* env);
178824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurkaextern int register_android_view_KeyCharacterMap(JNIEnv *env);
179824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurkaextern int register_android_view_KeyEvent(JNIEnv* env);
180c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_view_MotionEvent(JNIEnv* env);
181c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_view_PointerIcon(JNIEnv* env);
182c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_view_VelocityTracker(JNIEnv* env);
183c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseextern int register_android_content_res_ObbScanner(JNIEnv* env);
1844c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornextern int register_android_content_res_Configuration(JNIEnv* env);
185759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackbornextern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
18630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brownextern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
18730bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brownextern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env);
18830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brownextern int register_com_android_internal_os_Zygote(JNIEnv *env);
18930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brownextern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
190759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn
191209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlockstatic AndroidRuntime* gCurRuntime = NULL;
1929b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos
193a8e5a2bcd6a0d35893187c6df42425c03be005daChet Haase/*
1947e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * Code written in the Java Programming Language calls here from main().
1957e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos */
1964c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornstatic void com_android_internal_os_RuntimeInit_nativeFinishInit(JNIEnv* env, jobject clazz)
1974c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn{
1984c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    gCurRuntime->onStarted();
199284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn}
200284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn
2017670b2bd49915509dac72c98f2b6a2c1172c52bfjshestatic void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
2022acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos{
203284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn    gCurRuntime->onZygoteInit();
204284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn}
2057e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos
2067e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roosstatic void com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup(JNIEnv* env,
2077e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos        jobject clazz, jboolean exitWithoutCleanup)
2087e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos{
209824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    gCurRuntime->setExitWithoutCleanup(exitWithoutCleanup);
210824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka}
211824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka
212824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka/*
2137e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * JNI registration.
2147e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos */
2157e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roosstatic JNINativeMethod gMethods[] = {
216824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    { "nativeFinishInit", "()V",
2177e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos        (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
218824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    { "nativeZygoteInit", "()V",
219824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka        (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
220824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    { "nativeSetExitWithoutCleanup", "(Z)V",
2219b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos        (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
2229b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos};
223824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka
224ba39839444532af0ed3766f736582413f6d7a40bDianne Hackbornint register_com_android_internal_os_RuntimeInit(JNIEnv* env)
225ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn{
226ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn    return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",
227ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn        gMethods, NELEM(gMethods));
228824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka}
22930a7dfa329e79bab20f3b85dd376f736ebc6292dAdrian Roos
23030a7dfa329e79bab20f3b85dd376f736ebc6292dAdrian Roos// ----------------------------------------------------------------------
231ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn
232ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn/*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL;
233ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn
2347e9dec284128ef07024c85bc59f317f3e6726c23Adrian RoosAndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
235ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn        mExitWithoutCleanup(false),
236ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn        mArgBlockStart(argBlockStart),
237ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn        mArgBlockLength(argBlockLength)
238759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn{
23930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    SkGraphics::Init();
2402f20081f9fd734e466147bf1091d06cc7331458cChet Haase    // There is also a global font cache, but its budget is specified in code
24130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    // see SkFontHost_android.cpp
24230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown
243b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner    // Pre-allocate enough space to hold a fair number of options.
244b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner    mOptions.setCapacity(20);
245b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner
24630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    assert(gCurRuntime == NULL);        // one per process
247b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner    gCurRuntime = this;
2486b53fd28e5de1ef5263b4cffaf7c5b6d99005e76longyu.huang}
2496b53fd28e5de1ef5263b4cffaf7c5b6d99005e76longyu.huang
2506b53fd28e5de1ef5263b4cffaf7c5b6d99005e76longyu.huangAndroidRuntime::~AndroidRuntime()
251fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown{
252759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn    SkGraphics::Term();
253fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown}
254759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn
25572c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn/*
256bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen * Register native methods using JNI.
25772c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn */
25830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown/*static*/ int AndroidRuntime::registerNativeMethods(JNIEnv* env,
25930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    const char* className, const JNINativeMethod* gMethods, int numMethods)
26030bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown{
26130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    return jniRegisterNativeMethods(env, className, gMethods, numMethods);
26230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown}
26330bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown
264b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautnervoid AndroidRuntime::setArgv0(const char* argv0) {
265b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner    memset(mArgBlockStart, 0, mArgBlockLength);
266b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner    strlcpy(mArgBlockStart, argv0, mArgBlockLength);
267fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown}
268b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner
269b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautnerstatus_t AndroidRuntime::callMain(const String8& className, jclass clazz,
270b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner    const Vector<String8>& args)
271fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown{
272b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner    JNIEnv* env;
27372c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn    jmethodID methodId;
27472c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn
27572c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn    ALOGD("Calling main entry %s", className.string());
2764c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
27730bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    env = getJNIEnv();
27830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    if (clazz == NULL || env == NULL) {
279fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown        return UNKNOWN_ERROR;
2804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
28130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown
2824c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    methodId = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
283b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner    if (methodId == NULL) {
2844c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        ALOGE("ERROR: could not find method %s.main(String[])\n", className.string());
285fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown        return UNKNOWN_ERROR;
286fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner    }
2872f20081f9fd734e466147bf1091d06cc7331458cChet Haase
2882f20081f9fd734e466147bf1091d06cc7331458cChet Haase    /*
28953560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos     * We want to call main() with a String array with our arguments in it.
29053560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos     * Create an array and populate it.
29153560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos     */
29253560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos    jclass stringClass;
2935f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase    jobjectArray strArray;
29453560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos
2952f20081f9fd734e466147bf1091d06cc7331458cChet Haase    const size_t numArgs = args.size();
2962f20081f9fd734e466147bf1091d06cc7331458cChet Haase    stringClass = env->FindClass("java/lang/String");
2972f20081f9fd734e466147bf1091d06cc7331458cChet Haase    strArray = env->NewObjectArray(numArgs, stringClass, NULL);
2982f20081f9fd734e466147bf1091d06cc7331458cChet Haase
2992f20081f9fd734e466147bf1091d06cc7331458cChet Haase    for (size_t i = 0; i < numArgs; i++) {
30053560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos        jstring argStr = env->NewStringUTF(args[i].string());
30153560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos        env->SetObjectArrayElement(strArray, i, argStr);
30253560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos    }
30353560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos
3045f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase    env->CallStaticVoidMethod(clazz, methodId, strArray);
30553560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos    return NO_ERROR;
3062f20081f9fd734e466147bf1091d06cc7331458cChet Haase}
3072f20081f9fd734e466147bf1091d06cc7331458cChet Haase
3082f20081f9fd734e466147bf1091d06cc7331458cChet Haase/*
309fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner * The VM calls this through the "exit" hook.
310fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner */
3112f20081f9fd734e466147bf1091d06cc7331458cChet Haasestatic void runtime_exit(int code)
312fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner{
313fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner    gCurRuntime->exit(code);
314b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner}
315fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner
316fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner/*
3179b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos * The VM calls this through the "vfprintf" hook.
3189b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos *
3199b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos * We ignore "fp" and just write the results to the log file.
320824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka */
321824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurkastatic void runtime_vfprintf(FILE* fp, const char* format, va_list ap)
322b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner{
32353560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos    LOG_PRI_VA(ANDROID_LOG_INFO, "vm-printf", format, ap);
32453560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos}
32553560f1c8b7d290cf6db9de44df8210c9ed30ba7Adrian Roos
3262acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos/**
327c5887ea7a0b82cc5909743ce14cbda1dcf1dfc82Jorim Jaggi * The VM calls this when mutex contention debugging is enabled to
3289b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos * determine whether or not the blocked thread was a "sensitive thread"
3299b9947de5dd06e7ae21a30d95b243af043e71b96Adrian Roos * for user responsiveness/smoothess.
3302acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos *
3312acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos * Our policy for this is whether or not we're tracing any StrictMode
3322acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos * events on this thread (which we might've inherited via Binder calls
3332acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos * into us)
3342acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos */
3352acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roosstatic bool runtime_isSensitiveThread() {
3367e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    IPCThreadState* state = IPCThreadState::selfOrNull();
3377e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    return state && state->getStrictModePolicy() != 0;
3387e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos}
339ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos
340ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roosstatic int hasDir(const char* dir)
341ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos{
342fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown    struct stat s;
3432acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    int res = stat(dir, &s);
3442acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    if (res == 0) {
3452acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos        return S_ISDIR(s.st_mode);
3462acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    }
3472acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    return 0;
3482acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos}
349321357b6066a34cc12a0528b7b835c7664db2e08Michael Jurka
3502acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roosstatic bool hasFile(const char* file) {
3512acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    struct stat s;
3525f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase    int res = stat(file, &s);
3532acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    if (res == 0) {
3542acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos        return S_ISREG(s.st_mode);
3555f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase    }
3565f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase    return false;
3575f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase}
3582acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos
3592acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos/*
3607e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * Read the persistent locale. Attempts to read to persist.sys.locale
3617e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * and falls back to the default locale (ro.product.locale) if
3622acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos * persist.sys.locale is empty.
3632acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos */
3642acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roosstatic void readLocale(char* locale)
3652acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos{
3662acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    // Allocate 4 extra bytes because we might read a property into
3672acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    // this array at offset 4.
3682acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    char propLocale[PROPERTY_VALUE_MAX + 4];
3692acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos
3707e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    property_get("persist.sys.locale", propLocale, "");
3712acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    if (propLocale[0] == 0) {
3727e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos        property_get("ro.product.locale", propLocale, "");
3735f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase
3747e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos        if (propLocale[0] == 0) {
3755f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase            // If persist.sys.locale and ro.product.locale are missing,
376ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn            // construct a locale value from the individual locale components.
3772acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            property_get("ro.product.locale.language", propLocale, "en");
3782acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos
3792acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            // The language code is either two or three chars in length. If it
3802acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            // isn't 2 chars long, assume three. Anything else is an error
3812acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            // anyway.
3822acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            const int offset = (propLocale[2] == 0) ? 2 : 3;
3832acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            propLocale[offset] = '-';
3842acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos
3852acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            property_get("ro.product.locale.region", propLocale + offset + 1, "US");
3862acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos        }
3872acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    }
3882acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos
3892acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    strncat(locale, propLocale, PROPERTY_VALUE_MAX);
3902acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    // ALOGD("[DEBUG] locale=%s", locale);
3912acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos}
3922acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos
3932acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roosvoid AndroidRuntime::addOption(const char* optionString, void* extraInfo)
3942acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos{
3952acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    JavaVMOption opt;
3962acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    opt.optionString = optionString;
3972acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    opt.extraInfo = extraInfo;
3982acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    mOptions.add(opt);
399033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown}
4002acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos
4012acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos/*
4022acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos * Parse a property containing space-separated options that should be
4032acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos * passed directly to the VM, e.g. "-Xmx32m -verbose:gc -Xregenmap".
4042acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos *
4052acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos * This will cut up "extraOptsBuf" as we chop it into individual options.
4062acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos *
4072acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos * If "quotingArg" is non-null, it is passed before each extra option in mOptions.
4082acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos *
409033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown * Adds the strings, if any, to mOptions.
4102acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos */
4112acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roosvoid AndroidRuntime::parseExtraOpts(char* extraOptsBuf, const char* quotingArg)
4122acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos{
4139549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden    char* start = extraOptsBuf;
4142acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    char* end = NULL;
4152acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos    while (*start != '\0') {
4162acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos        while (*start == ' ')                   /* skip leading whitespace */
4172acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            start++;
4182acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos        if (*start == '\0')                     /* was trailing ws, bail */
419f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy            break;
420f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy
4212acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos        end = start+1;
422c5887ea7a0b82cc5909743ce14cbda1dcf1dfc82Jorim Jaggi        while (*end != ' ' && *end != '\0')     /* find end of token */
4232acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            end++;
424c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase        if (*end == ' ')
425c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase            *end++ = '\0';          /* mark end, advance to indicate more */
426c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase
427c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase        if (quotingArg != NULL) {
4282acaeda423aabf5c39c096fa88b51b4d820e2173Adrian Roos            addOption(quotingArg);
429c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase        }
430c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase        addOption(start);
431c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase        start = end;
432759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn    }
433759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn}
434ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy
4357e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos/*
4367e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * Reads a "property" into "buffer" with a default of "defaultArg". If
4377e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * the property is non-empty, it is treated as a runtime option such
4387e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * as "-Xmx32m".
4397e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
4407e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * The "runtimeArg" is a prefix for the option such as "-Xms" or "-Xmx".
4417e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
4427e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * If an argument is found, it is added to mOptions.
4437e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
4447e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * If an option is found, it is added to mOptions and true is
4457e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * returned. Otherwise false is returned.
4467e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos */
4477e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roosbool AndroidRuntime::parseRuntimeOption(const char* property,
4487e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos                                        char* buffer,
449fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown                                        const char* runtimeArg,
4507e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos                                        const char* defaultArg)
4517e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos{
4527e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    strcpy(buffer, runtimeArg);
4537e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    size_t runtimeArgLen = strlen(runtimeArg);
4547e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    property_get(property, buffer+runtimeArgLen, defaultArg);
4557e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    if (buffer[runtimeArgLen] == '\0') {
4567e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos        return false;
4577e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    }
4587e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    addOption(buffer);
459407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    return true;
4607e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos}
4617e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos
4627e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos/*
4637e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * Reads a "property" into "buffer". If the property is non-empty, it
4647e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * is treated as a dex2oat compiler option that should be
4657e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * passed as a quoted option, e.g. "-Ximage-compiler-option --compiler-filter=verify-none".
4667e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
4677e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * The "compilerArg" is a prefix for the option such as "--compiler-filter=".
4687e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
4697e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * The "quotingArg" should be "-Ximage-compiler-option" or "-Xcompiler-option".
4707e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
4717e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * If an option is found, it is added to mOptions and true is
4727e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * returned. Otherwise false is returned.
4737e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos */
4747e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roosbool AndroidRuntime::parseCompilerOption(const char* property,
4757e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos                                         char* buffer,
4767e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos                                         const char* compilerArg,
4777e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos                                         const char* quotingArg)
4787e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos{
479c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn    strcpy(buffer, compilerArg);
4807e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    size_t compilerArgLen = strlen(compilerArg);
4817e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    property_get(property, buffer+compilerArgLen, "");
4827e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    if (buffer[compilerArgLen] == '\0') {
4837e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos        return false;
4847e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    }
4857e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    addOption(quotingArg);
4867e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    addOption(buffer);
4877e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos    return true;
4887e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos}
4897e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos
4907e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos/*
4917e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * Reads a "property" into "buffer". If the property is non-empty, it
4927e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * is treated as a dex2oat compiler runtime option that should be
4937e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * passed as a quoted option, e.g. "-Ximage-compiler-option
4947e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * --runtime-arg -Ximage-compiler-option -Xmx32m".
4957e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
4967e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * The "runtimeArg" is a prefix for the option such as "-Xms" or "-Xmx".
4977e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
4987e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * The "quotingArg" should be "-Ximage-compiler-option" or "-Xcompiler-option".
4997e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos *
5007e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * If an option is found, it is added to mOptions and true is
5017e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos * returned. Otherwise false is returned.
5027e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos */
5037e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roosbool AndroidRuntime::parseCompilerRuntimeOption(const char* property,
5047e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos                                                char* buffer,
5057e9dec284128ef07024c85bc59f317f3e6726c23Adrian Roos                                                const char* runtimeArg,
506407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                                                const char* quotingArg)
507407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy{
508ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    strcpy(buffer, runtimeArg);
509ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    size_t runtimeArgLen = strlen(runtimeArg);
510ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    property_get(property, buffer+runtimeArgLen, "");
511ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    if (buffer[runtimeArgLen] == '\0') {
512ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos        return false;
513ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    }
514ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    addOption(quotingArg);
515ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    addOption("--runtime-arg");
516ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    addOption(quotingArg);
517ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    addOption(buffer);
518ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    return true;
519ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos}
520ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos
521ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos/*
522ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos * Start the Dalvik Virtual Machine.
523ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos *
524ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos * Various arguments, most determined by system properties, are passed in.
525ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos * The "mOptions" vector is updated.
526ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos *
527ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos * CAUTION: when adding options in here, be careful not to put the
528ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos * char buffer inside a nested scope.  Adding the buffer to the
529ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos * options using mOptions.add() does not copy the buffer, so if the
530ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos * buffer goes out of scope the option may be overwritten.  It's best
53130a7dfa329e79bab20f3b85dd376f736ebc6292dAdrian Roos * to put the buffer at the top of the function so that it is more
53230a7dfa329e79bab20f3b85dd376f736ebc6292dAdrian Roos * unlikely that someone will surround it in a scope at a later time
53330a7dfa329e79bab20f3b85dd376f736ebc6292dAdrian Roos * and thus introduce a bug.
534ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos *
535ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos * Returns 0 on success.
536ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos */
537ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roosint AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
538ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos{
539ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    int result = -1;
540ab6edbf8e09a856bf638d0a1fcdd1e0d1f708574Adrian Roos    JavaVMInitArgs initArgs;
541824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char propBuf[PROPERTY_VALUE_MAX];
542407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];
543407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
544407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
545407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
546824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
547407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
548407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
549824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
550824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];
551407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
552407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char dex2oatXmsImageFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
553824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char dex2oatXmxImageFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
5545f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase    char dex2oatXmsFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
555407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char dex2oatXmxFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
556407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char dex2oatCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];
557407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char dex2oatImageCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];
558407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char dex2oatFlagsBuf[PROPERTY_VALUE_MAX];
559824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX];
560824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char extraOptsBuf[PROPERTY_VALUE_MAX];
561824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char voldDecryptBuf[PROPERTY_VALUE_MAX];
562407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    enum {
563407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy      kEMDefault,
564407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy      kEMIntPortable,
565407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy      kEMIntFast,
566407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy      kEMJitCompiler,
567407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    } executionMode = kEMDefault;
568407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char profilePeriod[sizeof("-Xprofile-period:")-1 + PROPERTY_VALUE_MAX];
569f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy    char profileDuration[sizeof("-Xprofile-duration:")-1 + PROPERTY_VALUE_MAX];
570f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy    char profileInterval[sizeof("-Xprofile-interval:")-1 + PROPERTY_VALUE_MAX];
571407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char profileBackoff[sizeof("-Xprofile-backoff:")-1 + PROPERTY_VALUE_MAX];
572824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char profileTopKThreshold[sizeof("-Xprofile-top-k-threshold:")-1 + PROPERTY_VALUE_MAX];
573824a4b5ea4c58592b9b2ebe787f5fb6974e7cabeMichael Jurka    char profileTopKChangeThreshold[sizeof("-Xprofile-top-k-change-threshold:")-1 +
574407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                                    PROPERTY_VALUE_MAX];
575407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char profileType[sizeof("-Xprofile-type:")-1 + PROPERTY_VALUE_MAX];
576407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char profileMaxStackDepth[sizeof("-Xprofile-max-stack-depth:")-1 + PROPERTY_VALUE_MAX];
577407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX];
578407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
579407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
580407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
581407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    bool checkJni = false;
582407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    property_get("dalvik.vm.checkjni", propBuf, "");
5832f20081f9fd734e466147bf1091d06cc7331458cChet Haase    if (strcmp(propBuf, "true") == 0) {
584407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        checkJni = true;
585407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    } else if (strcmp(propBuf, "false") != 0) {
586407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        /* property is neither true nor false; fall back on kernel parameter */
587407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        property_get("ro.kernel.android.checkjni", propBuf, "");
588407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        if (propBuf[0] == '1') {
589407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            checkJni = true;
590407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        }
591407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
592407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
593407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (checkJni) {
594407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        /* extended JNI checking */
595407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("-Xcheck:jni");
596407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
597407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        /* with -Xcheck:jni, this provides a JNI function call trace */
598407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        //addOption("-verbose:jni");
599407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
600407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
601407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    property_get("dalvik.vm.execution-mode", propBuf, "");
6026762a441ef9c764f3bfee4201742e80aa6621b89Michael Wright    if (strcmp(propBuf, "int:portable") == 0) {
603407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        executionMode = kEMIntPortable;
604407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    } else if (strcmp(propBuf, "int:fast") == 0) {
605407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        executionMode = kEMIntFast;
6062f20081f9fd734e466147bf1091d06cc7331458cChet Haase    } else if (strcmp(propBuf, "int:jit") == 0) {
607407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        executionMode = kEMJitCompiler;
608407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
609407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
610407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:");
611407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
612407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    strcpy(jniOptsBuf, "-Xjniopts:");
613407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (parseRuntimeOption("dalvik.vm.jniopts", jniOptsBuf, "-Xjniopts:")) {
614407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        ALOGI("JNI options: '%s'\n", jniOptsBuf);
615407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
616407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
6172f20081f9fd734e466147bf1091d06cc7331458cChet Haase    /* route exit() to our handler */
618c8d983f7259b4e328abc10c27c3c2cec61ad0722Romain Guy    addOption("exit", (void*) runtime_exit);
619407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
6202f20081f9fd734e466147bf1091d06cc7331458cChet Haase    /* route fprintf() to our handler */
6212ed0513f20dea3ba97d09b528879301c86f31884Michael Wright    addOption("vfprintf", (void*) runtime_vfprintf);
622f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy
623c8d983f7259b4e328abc10c27c3c2cec61ad0722Romain Guy    /* register the framework-specific "is sensitive thread" hook */
624407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    addOption("sensitiveThread", (void*) runtime_isSensitiveThread);
625407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
626407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    /* enable verbose; standard options are { jni, gc, class } */
627407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    //addOption("-verbose:jni");
628407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    addOption("-verbose:gc");
629407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    //addOption("-verbose:class");
630407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
631407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    /*
632407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     * The default starting and maximum size of the heap.  Larger
633407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     * values should be specified in a product property override.
634407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     */
635407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
636407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
637407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
638407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
639407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree=");
640407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");
641407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.heaptargetutilization",
642407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                       heaptargetutilizationOptsBuf,
643407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                       "-XX:HeapTargetUtilization=");
644209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
645407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    property_get("ro.config.low_ram", propBuf, "");
646407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (strcmp(propBuf, "true") == 0) {
647407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy      addOption("-XX:LowMemoryMode");
648209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock    }
649407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
650407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:");
651407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.backgroundgctype", backgroundgcOptsBuf, "-XX:BackgroundGC=");
652209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
653407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    /* enable debugging; set suspend=y to pause during VM init */
654407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    /* use android ADB transport */
655209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock    addOption("-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y");
656407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
657407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.lockprof.threshold",
658209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock                       lockProfThresholdBuf,
659407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                       "-Xlockprofthreshold:");
660407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
661407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (executionMode == kEMIntPortable) {
662407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("-Xint:portable");
663407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    } else if (executionMode == kEMIntFast) {
664209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock        addOption("-Xint:fast");
665407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    } else if (executionMode == kEMJitCompiler) {
666407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("-Xint:jit");
667407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
668209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
669407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // If we are booting without the real /data, don't spend time compiling.
670407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    property_get("vold.decrypt", voldDecryptBuf, "");
671209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock    bool skip_compilation = ((strcmp(voldDecryptBuf, "trigger_restart_min_framework") == 0) ||
672407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                             (strcmp(voldDecryptBuf, "1") == 0));
673407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
674407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // Extra options for boot.art/boot.oat image generation.
675407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xms", dex2oatXmsImageFlagsBuf,
676407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                               "-Xms", "-Ximage-compiler-option");
677209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock    parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xmx", dex2oatXmxImageFlagsBuf,
6782ed0513f20dea3ba97d09b528879301c86f31884Michael Wright                               "-Xmx", "-Ximage-compiler-option");
6792ed0513f20dea3ba97d09b528879301c86f31884Michael Wright    if (skip_compilation) {
6802ed0513f20dea3ba97d09b528879301c86f31884Michael Wright        addOption("-Ximage-compiler-option");
681407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("--compiler-filter=verify-none");
682407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    } else {
683407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf,
684407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                            "--compiler-filter=", "-Ximage-compiler-option");
685407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
686407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
687407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // Make sure there is a preloaded-classes file.
688407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (!hasFile("/system/etc/preloaded-classes")) {
689209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock        ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n",
690407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy              strerror(errno));
691407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        goto bail;
6923696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy    }
693407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    addOption("-Ximage-compiler-option");
694407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    addOption("--image-classes=/system/etc/preloaded-classes");
695209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
696407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // If there is a compiled-classes file, push it.
697407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (hasFile("/system/etc/compiled-classes")) {
698209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock        addOption("-Ximage-compiler-option");
699407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("--compiled-classes=/system/etc/compiled-classes");
700407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
701209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
702407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
703407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option");
704407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
705407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // Extra options for DexClassLoader.
706407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xms", dex2oatXmsFlagsBuf,
707407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                               "-Xms", "-Xcompiler-option");
708407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseCompilerRuntimeOption("dalvik.vm.dex2oat-Xmx", dex2oatXmxFlagsBuf,
709407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                               "-Xmx", "-Xcompiler-option");
710209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock    if (skip_compilation) {
711407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("-Xcompiler-option");
712407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("--compiler-filter=verify-none");
7133696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy
714407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        // We skip compilation when a minimal runtime is brought up for decryption. In that case
715407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        // /data is temporarily backed by a tmpfs, which is usually small.
716407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        // If the system image contains prebuilts, they will be relocated into the tmpfs. In this
717407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        // specific situation it is acceptable to *not* relocate and run out of the prebuilts
718407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        // directly instead.
719407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("--runtime-arg");
7203696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy        addOption("-Xnorelocate");
721407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    } else {
722407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        parseCompilerOption("dalvik.vm.dex2oat-filter", dex2oatCompilerFilterBuf,
723407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                            "--compiler-filter=", "-Xcompiler-option");
724407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
725407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    property_get("dalvik.vm.dex2oat-flags", dex2oatFlagsBuf, "");
726407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseExtraOpts(dex2oatFlagsBuf, "-Xcompiler-option");
7273696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy
7282ed0513f20dea3ba97d09b528879301c86f31884Michael Wright    /* extra options; parse this late so it overrides others */
7292ed0513f20dea3ba97d09b528879301c86f31884Michael Wright    property_get("dalvik.vm.extra-opts", extraOptsBuf, "");
7302ed0513f20dea3ba97d09b528879301c86f31884Michael Wright    parseExtraOpts(extraOptsBuf, NULL);
7312ed0513f20dea3ba97d09b528879301c86f31884Michael Wright
7322ed0513f20dea3ba97d09b528879301c86f31884Michael Wright    /* Set the properties for locale */
733f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy    {
734407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        strcpy(localeOption, "-Duser.locale=");
735f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy        readLocale(localeOption);
7363696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy        addOption(localeOption);
737407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
7383696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy
739f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy    /*
740407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     * Set profiler options
741209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock     */
742407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // Whether or not the profiler should be enabled.
743407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    property_get("dalvik.vm.profiler", propBuf, "0");
744407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (propBuf[0] == '1') {
745407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("-Xenable-profiler");
746407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
747209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock
748407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // Whether the profile should start upon app startup or be delayed by some random offset
749407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // (in seconds) that is bound between 0 and a fixed value.
750407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    property_get("dalvik.vm.profile.start-immed", propBuf, "0");
751407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (propBuf[0] == '1') {
752407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        addOption("-Xprofile-start-immediately");
753209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock    }
754407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
755407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    // Number of seconds during profile runs.
756407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.profile.period-secs", profilePeriod, "-Xprofile-period:");
757407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
758209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock    // Length of each profile run (seconds).
759407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.profile.duration-secs",
760187e1e2fc7dfb4eabdcb2c8990774bc6020fb16bChet Haase                       profileDuration,
761187e1e2fc7dfb4eabdcb2c8990774bc6020fb16bChet Haase                       "-Xprofile-duration:");
762187e1e2fc7dfb4eabdcb2c8990774bc6020fb16bChet Haase
7639549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden    // Polling interval during profile run (microseconds).
764187e1e2fc7dfb4eabdcb2c8990774bc6020fb16bChet Haase    parseRuntimeOption("dalvik.vm.profile.interval-us", profileInterval, "-Xprofile-interval:");
7652e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase
7662e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // Coefficient for period backoff.  The the period is multiplied
7672e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // by this value after each profile run.
7682e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    parseRuntimeOption("dalvik.vm.profile.backoff-coeff", profileBackoff, "-Xprofile-backoff:");
7692e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase
7702e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // Top K% of samples that are considered relevant when
7712e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // deciding if the app should be recompiled.
7722e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    parseRuntimeOption("dalvik.vm.profile.top-k-thr",
7732e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase                       profileTopKThreshold,
7742e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase                       "-Xprofile-top-k-threshold:");
7752e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase
7762e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // The threshold after which a change in the structure of the
7772e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // top K% profiled samples becomes significant and triggers
7782e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // recompilation. A change in profile is considered
7792e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // significant if X% (top-k-change-threshold) of the top K%
7802e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // (top-k-threshold property) samples has changed.
7812e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    parseRuntimeOption("dalvik.vm.profile.top-k-ch-thr",
7822e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase                       profileTopKChangeThreshold,
7832e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase                       "-Xprofile-top-k-change-threshold:");
7842e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase
7852e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // Type of profile data.
7862e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    parseRuntimeOption("dalvik.vm.profiler.type", profileType, "-Xprofile-type:");
7872e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase
7882e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase    // Depth of bounded stack data
789407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    parseRuntimeOption("dalvik.vm.profile.stack-depth",
790407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                       profileMaxStackDepth,
791407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                       "-Xprofile-max-stack-depth:");
7929549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden
7939549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden    // Native bridge library. "0" means that native bridge is disabled.
7949549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden    property_get("ro.dalvik.vm.native.bridge", propBuf, "");
795f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy    if (propBuf[0] == '\0') {
796407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        ALOGW("ro.dalvik.vm.native.bridge is not expected to be empty");
797407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    } else if (strcmp(propBuf, "0") != 0) {
798407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        snprintf(nativeBridgeLibrary, sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX,
799407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                 "-XX:NativeBridge=%s", propBuf);
800209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock        addOption(nativeBridgeLibrary);
801407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
802407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
803407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    initArgs.version = JNI_VERSION_1_4;
804407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    initArgs.options = mOptions.editArray();
805f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy    initArgs.nOptions = mOptions.size();
806f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy    initArgs.ignoreUnrecognized = JNI_FALSE;
807407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
808209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock    /*
809209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock     * Initialize the VM.
810407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     *
811407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
812209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock     * If this call succeeds, the VM is ready, and we can start issuing
813407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     * JNI calls.
814209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock     */
815407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
816407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        ALOGE("JNI_CreateJavaVM failed\n");
817407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        goto bail;
818407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
819407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
820407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    result = 0;
821407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
822407ec78b828173257b0c5dae221649a4ccd8b058Romain Guybail:
823407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    return result;
824407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy}
825407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
826407ec78b828173257b0c5dae221649a4ccd8b058Romain Guychar* AndroidRuntime::toSlashClassName(const char* className)
827407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy{
828407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    char* result = strdup(className);
829407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    for (char* cp = result; *cp != '\0'; cp++) {
830407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        if (*cp == '.') {
831407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            *cp = '/';
832407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        }
833407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
834407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    return result;
835407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy}
836407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
8378efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy/** Create a Java string from an ASCII or Latin-1 string */
838407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyjstring AndroidRuntime::NewStringLatin1(JNIEnv* env, const char* bytes) {
839407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    if (!bytes) return NULL;
840ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy    int length = strlen(bytes);
8414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    jchar* buffer = (jchar *)alloca(length * sizeof(jchar));
8424c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    if (!buffer) return NULL;
843    jchar* chp = buffer;
844    for (int i = 0; i < length; i++) {
845        *chp++ = *bytes++;
846    }
847    return env->NewString(buffer, length);
848}
849
850
851/*
852 * Start the Android runtime.  This involves starting the virtual machine
853 * and calling the "static void main(String[] args)" method in the class
854 * named by "className".
855 *
856 * Passes the main function two arguments, the class name and the specified
857 * options string.
858 */
859void AndroidRuntime::start(const char* className, const Vector<String8>& options)
860{
861    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
862            className != NULL ? className : "(unknown)", getuid());
863
864    static const String8 startSystemServer("start-system-server");
865
866    /*
867     * 'startSystemServer == true' means runtime is obsolete and not run from
868     * init.rc anymore, so we print out the boot start event here.
869     */
870    for (size_t i = 0; i < options.size(); ++i) {
871        if (options[i] == startSystemServer) {
872           /* track our progress through the boot sequence */
873           const int LOG_BOOT_PROGRESS_START = 3000;
874           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
875        }
876    }
877
878    const char* rootDir = getenv("ANDROID_ROOT");
879    if (rootDir == NULL) {
880        rootDir = "/system";
881        if (!hasDir("/system")) {
882            LOG_FATAL("No root directory specified, and /android does not exist.");
883            return;
884        }
885        setenv("ANDROID_ROOT", rootDir, 1);
886    }
887
888    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
889    //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
890
891    /* start the virtual machine */
892    JniInvocation jni_invocation;
893    jni_invocation.Init(NULL);
894    JNIEnv* env;
895    if (startVm(&mJavaVM, &env) != 0) {
896        return;
897    }
898    onVmCreated(env);
899
900    /*
901     * Register android functions.
902     */
903    if (startReg(env) < 0) {
904        ALOGE("Unable to register all android natives\n");
905        return;
906    }
907
908    /*
909     * We want to call main() with a String array with arguments in it.
910     * At present we have two arguments, the class name and an option string.
911     * Create an array to hold them.
912     */
913    jclass stringClass;
914    jobjectArray strArray;
915    jstring classNameStr;
916
917    stringClass = env->FindClass("java/lang/String");
918    assert(stringClass != NULL);
919    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
920    assert(strArray != NULL);
921    classNameStr = env->NewStringUTF(className);
922    assert(classNameStr != NULL);
923    env->SetObjectArrayElement(strArray, 0, classNameStr);
924
925    for (size_t i = 0; i < options.size(); ++i) {
926        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
927        assert(optionsStr != NULL);
928        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
929    }
930
931    /*
932     * Start VM.  This thread becomes the main thread of the VM, and will
933     * not return until the VM exits.
934     */
935    char* slashClassName = toSlashClassName(className);
936    jclass startClass = env->FindClass(slashClassName);
937    if (startClass == NULL) {
938        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
939        /* keep going */
940    } else {
941        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
942            "([Ljava/lang/String;)V");
943        if (startMeth == NULL) {
944            ALOGE("JavaVM unable to find main() in '%s'\n", className);
945            /* keep going */
946        } else {
947            env->CallStaticVoidMethod(startClass, startMeth, strArray);
948
949#if 0
950            if (env->ExceptionCheck())
951                threadExitUncaughtException(env);
952#endif
953        }
954    }
955    free(slashClassName);
956
957    ALOGD("Shutting down VM\n");
958    if (mJavaVM->DetachCurrentThread() != JNI_OK)
959        ALOGW("Warning: unable to detach main thread\n");
960    if (mJavaVM->DestroyJavaVM() != 0)
961        ALOGW("Warning: VM did not shut down cleanly\n");
962}
963
964void AndroidRuntime::exit(int code)
965{
966    if (mExitWithoutCleanup) {
967        ALOGI("VM exiting with result code %d, cleanup skipped.", code);
968        ::_exit(code);
969    } else {
970        ALOGI("VM exiting with result code %d.", code);
971        onExit(code);
972        ::exit(code);
973    }
974}
975
976void AndroidRuntime::onVmCreated(JNIEnv* env)
977{
978    // If AndroidRuntime had anything to do here, we'd have done it in 'start'.
979}
980
981/*
982 * Get the JNIEnv pointer for this thread.
983 *
984 * Returns NULL if the slot wasn't allocated or populated.
985 */
986/*static*/ JNIEnv* AndroidRuntime::getJNIEnv()
987{
988    JNIEnv* env;
989    JavaVM* vm = AndroidRuntime::getJavaVM();
990    assert(vm != NULL);
991
992    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
993        return NULL;
994    return env;
995}
996
997/*
998 * Makes the current thread visible to the VM.
999 *
1000 * The JNIEnv pointer returned is only valid for the current thread, and
1001 * thus must be tucked into thread-local storage.
1002 */
1003static int javaAttachThread(const char* threadName, JNIEnv** pEnv)
1004{
1005    JavaVMAttachArgs args;
1006    JavaVM* vm;
1007    jint result;
1008
1009    vm = AndroidRuntime::getJavaVM();
1010    assert(vm != NULL);
1011
1012    args.version = JNI_VERSION_1_4;
1013    args.name = (char*) threadName;
1014    args.group = NULL;
1015
1016    result = vm->AttachCurrentThread(pEnv, (void*) &args);
1017    if (result != JNI_OK)
1018        ALOGI("NOTE: attach of thread '%s' failed\n", threadName);
1019
1020    return result;
1021}
1022
1023/*
1024 * Detach the current thread from the set visible to the VM.
1025 */
1026static int javaDetachThread(void)
1027{
1028    JavaVM* vm;
1029    jint result;
1030
1031    vm = AndroidRuntime::getJavaVM();
1032    assert(vm != NULL);
1033
1034    result = vm->DetachCurrentThread();
1035    if (result != JNI_OK)
1036        ALOGE("ERROR: thread detach failed\n");
1037    return result;
1038}
1039
1040/*
1041 * When starting a native thread that will be visible from the VM, we
1042 * bounce through this to get the right attach/detach action.
1043 * Note that this function calls free(args)
1044 */
1045/*static*/ int AndroidRuntime::javaThreadShell(void* args) {
1046    void* start = ((void**)args)[0];
1047    void* userData = ((void **)args)[1];
1048    char* name = (char*) ((void **)args)[2];        // we own this storage
1049    free(args);
1050    JNIEnv* env;
1051    int result;
1052
1053    /* hook us into the VM */
1054    if (javaAttachThread(name, &env) != JNI_OK)
1055        return -1;
1056
1057    /* start the thread running */
1058    result = (*(android_thread_func_t)start)(userData);
1059
1060    /* unhook us */
1061    javaDetachThread();
1062    free(name);
1063
1064    return result;
1065}
1066
1067/*
1068 * This is invoked from androidCreateThreadEtc() via the callback
1069 * set with androidSetCreateThreadFunc().
1070 *
1071 * We need to create the new thread in such a way that it gets hooked
1072 * into the VM before it really starts executing.
1073 */
1074/*static*/ int AndroidRuntime::javaCreateThreadEtc(
1075                                android_thread_func_t entryFunction,
1076                                void* userData,
1077                                const char* threadName,
1078                                int32_t threadPriority,
1079                                size_t threadStackSize,
1080                                android_thread_id_t* threadId)
1081{
1082    void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
1083    int result;
1084
1085    if (!threadName)
1086        threadName = "unnamed thread";
1087
1088    args[0] = (void*) entryFunction;
1089    args[1] = userData;
1090    args[2] = (void*) strdup(threadName);   // javaThreadShell must free
1091
1092    result = androidCreateRawThreadEtc(AndroidRuntime::javaThreadShell, args,
1093        threadName, threadPriority, threadStackSize, threadId);
1094    return result;
1095}
1096
1097/*
1098 * Create a thread that is visible from the VM.
1099 *
1100 * This is called from elsewhere in the library.
1101 */
1102/*static*/ android_thread_id_t AndroidRuntime::createJavaThread(const char* name,
1103    void (*start)(void *), void* arg)
1104{
1105    android_thread_id_t threadId = 0;
1106    javaCreateThreadEtc((android_thread_func_t) start, arg, name,
1107        ANDROID_PRIORITY_DEFAULT, 0, &threadId);
1108    return threadId;
1109}
1110
1111#if 0
1112static void quickTest(void* arg)
1113{
1114    const char* str = (const char*) arg;
1115
1116    printf("In quickTest: %s\n", str);
1117}
1118#endif
1119
1120#ifdef NDEBUG
1121    #define REG_JNI(name)      { name }
1122    struct RegJNIRec {
1123        int (*mProc)(JNIEnv*);
1124    };
1125#else
1126    #define REG_JNI(name)      { name, #name }
1127    struct RegJNIRec {
1128        int (*mProc)(JNIEnv*);
1129        const char* mName;
1130    };
1131#endif
1132
1133typedef void (*RegJAMProc)();
1134
1135static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
1136{
1137    for (size_t i = 0; i < count; i++) {
1138        if (array[i].mProc(env) < 0) {
1139#ifndef NDEBUG
1140            ALOGD("----------!!! %s failed to load\n", array[i].mName);
1141#endif
1142            return -1;
1143        }
1144    }
1145    return 0;
1146}
1147
1148static const RegJNIRec gRegJNI[] = {
1149    REG_JNI(register_com_android_internal_os_RuntimeInit),
1150    REG_JNI(register_android_os_SystemClock),
1151    REG_JNI(register_android_util_EventLog),
1152    REG_JNI(register_android_util_Log),
1153    REG_JNI(register_android_content_AssetManager),
1154    REG_JNI(register_android_content_StringBlock),
1155    REG_JNI(register_android_content_XmlBlock),
1156    REG_JNI(register_android_emoji_EmojiFactory),
1157    REG_JNI(register_android_text_AndroidCharacter),
1158    REG_JNI(register_android_text_StaticLayout),
1159    REG_JNI(register_android_text_AndroidBidi),
1160    REG_JNI(register_android_view_InputDevice),
1161    REG_JNI(register_android_view_KeyCharacterMap),
1162    REG_JNI(register_android_os_Process),
1163    REG_JNI(register_android_os_SystemProperties),
1164    REG_JNI(register_android_os_Binder),
1165    REG_JNI(register_android_os_Parcel),
1166    REG_JNI(register_android_nio_utils),
1167    REG_JNI(register_android_graphics_Graphics),
1168    REG_JNI(register_android_view_DisplayEventReceiver),
1169    REG_JNI(register_android_view_RenderNode),
1170    REG_JNI(register_android_view_RenderNodeAnimator),
1171    REG_JNI(register_android_view_GraphicBuffer),
1172    REG_JNI(register_android_view_GLES20Canvas),
1173    REG_JNI(register_android_view_HardwareLayer),
1174    REG_JNI(register_android_view_ThreadedRenderer),
1175    REG_JNI(register_android_view_Surface),
1176    REG_JNI(register_android_view_SurfaceControl),
1177    REG_JNI(register_android_view_SurfaceSession),
1178    REG_JNI(register_android_view_TextureView),
1179    REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper),
1180    REG_JNI(register_com_google_android_gles_jni_EGLImpl),
1181    REG_JNI(register_com_google_android_gles_jni_GLImpl),
1182    REG_JNI(register_android_opengl_jni_EGL14),
1183    REG_JNI(register_android_opengl_jni_EGLExt),
1184    REG_JNI(register_android_opengl_jni_GLES10),
1185    REG_JNI(register_android_opengl_jni_GLES10Ext),
1186    REG_JNI(register_android_opengl_jni_GLES11),
1187    REG_JNI(register_android_opengl_jni_GLES11Ext),
1188    REG_JNI(register_android_opengl_jni_GLES20),
1189    REG_JNI(register_android_opengl_jni_GLES30),
1190    REG_JNI(register_android_opengl_jni_GLES31),
1191    REG_JNI(register_android_opengl_jni_GLES31Ext),
1192
1193    REG_JNI(register_android_graphics_Bitmap),
1194    REG_JNI(register_android_graphics_BitmapFactory),
1195    REG_JNI(register_android_graphics_BitmapRegionDecoder),
1196    REG_JNI(register_android_graphics_Camera),
1197    REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
1198    REG_JNI(register_android_graphics_Canvas),
1199    REG_JNI(register_android_graphics_CanvasProperty),
1200    REG_JNI(register_android_graphics_ColorFilter),
1201    REG_JNI(register_android_graphics_DrawFilter),
1202    REG_JNI(register_android_graphics_FontFamily),
1203    REG_JNI(register_android_graphics_Interpolator),
1204    REG_JNI(register_android_graphics_LayerRasterizer),
1205    REG_JNI(register_android_graphics_MaskFilter),
1206    REG_JNI(register_android_graphics_Matrix),
1207    REG_JNI(register_android_graphics_Movie),
1208    REG_JNI(register_android_graphics_NinePatch),
1209    REG_JNI(register_android_graphics_Paint),
1210    REG_JNI(register_android_graphics_Path),
1211    REG_JNI(register_android_graphics_PathMeasure),
1212    REG_JNI(register_android_graphics_PathEffect),
1213    REG_JNI(register_android_graphics_Picture),
1214    REG_JNI(register_android_graphics_PorterDuff),
1215    REG_JNI(register_android_graphics_Rasterizer),
1216    REG_JNI(register_android_graphics_Region),
1217    REG_JNI(register_android_graphics_Shader),
1218    REG_JNI(register_android_graphics_SurfaceTexture),
1219    REG_JNI(register_android_graphics_Typeface),
1220    REG_JNI(register_android_graphics_Xfermode),
1221    REG_JNI(register_android_graphics_YuvImage),
1222    REG_JNI(register_android_graphics_pdf_PdfDocument),
1223    REG_JNI(register_android_graphics_pdf_PdfEditor),
1224    REG_JNI(register_android_graphics_pdf_PdfRenderer),
1225
1226    REG_JNI(register_android_database_CursorWindow),
1227    REG_JNI(register_android_database_SQLiteConnection),
1228    REG_JNI(register_android_database_SQLiteGlobal),
1229    REG_JNI(register_android_database_SQLiteDebug),
1230    REG_JNI(register_android_os_Debug),
1231    REG_JNI(register_android_os_FileObserver),
1232    REG_JNI(register_android_os_MessageQueue),
1233    REG_JNI(register_android_os_SELinux),
1234    REG_JNI(register_android_os_Trace),
1235    REG_JNI(register_android_os_UEventObserver),
1236    REG_JNI(register_android_net_LocalSocketImpl),
1237    REG_JNI(register_android_net_NetworkUtils),
1238    REG_JNI(register_android_net_TrafficStats),
1239    REG_JNI(register_android_os_MemoryFile),
1240    REG_JNI(register_com_android_internal_os_Zygote),
1241    REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
1242    REG_JNI(register_android_hardware_Camera),
1243    REG_JNI(register_android_hardware_camera2_CameraMetadata),
1244    REG_JNI(register_android_hardware_camera2_legacy_LegacyCameraDevice),
1245    REG_JNI(register_android_hardware_camera2_legacy_PerfMeasurement),
1246    REG_JNI(register_android_hardware_camera2_DngCreator),
1247    REG_JNI(register_android_hardware_SensorManager),
1248    REG_JNI(register_android_hardware_SerialPort),
1249    REG_JNI(register_android_hardware_SoundTrigger),
1250    REG_JNI(register_android_hardware_UsbDevice),
1251    REG_JNI(register_android_hardware_UsbDeviceConnection),
1252    REG_JNI(register_android_hardware_UsbRequest),
1253    REG_JNI(register_android_hardware_location_ActivityRecognitionHardware),
1254    REG_JNI(register_android_media_AudioRecord),
1255    REG_JNI(register_android_media_AudioSystem),
1256    REG_JNI(register_android_media_AudioTrack),
1257    REG_JNI(register_android_media_JetPlayer),
1258    REG_JNI(register_android_media_RemoteDisplay),
1259    REG_JNI(register_android_media_ToneGenerator),
1260
1261    REG_JNI(register_android_opengl_classes),
1262    REG_JNI(register_android_server_NetworkManagementSocketTagger),
1263    REG_JNI(register_android_ddm_DdmHandleNativeHeap),
1264    REG_JNI(register_android_backup_BackupDataInput),
1265    REG_JNI(register_android_backup_BackupDataOutput),
1266    REG_JNI(register_android_backup_FileBackupHelperBase),
1267    REG_JNI(register_android_backup_BackupHelperDispatcher),
1268    REG_JNI(register_android_app_backup_FullBackup),
1269    REG_JNI(register_android_app_ActivityThread),
1270    REG_JNI(register_android_app_NativeActivity),
1271    REG_JNI(register_android_view_InputChannel),
1272    REG_JNI(register_android_view_InputEventReceiver),
1273    REG_JNI(register_android_view_InputEventSender),
1274    REG_JNI(register_android_view_InputQueue),
1275    REG_JNI(register_android_view_KeyEvent),
1276    REG_JNI(register_android_view_MotionEvent),
1277    REG_JNI(register_android_view_PointerIcon),
1278    REG_JNI(register_android_view_VelocityTracker),
1279
1280    REG_JNI(register_android_content_res_ObbScanner),
1281    REG_JNI(register_android_content_res_Configuration),
1282
1283    REG_JNI(register_android_animation_PropertyValuesHolder),
1284    REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
1285    REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
1286};
1287
1288/*
1289 * Register android native functions with the VM.
1290 */
1291/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
1292{
1293    /*
1294     * This hook causes all future threads created in this process to be
1295     * attached to the JavaVM.  (This needs to go away in favor of JNI
1296     * Attach calls.)
1297     */
1298    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
1299
1300    ALOGV("--- registering native functions ---\n");
1301
1302    /*
1303     * Every "register" function calls one or more things that return
1304     * a local reference (e.g. FindClass).  Because we haven't really
1305     * started the VM yet, they're all getting stored in the base frame
1306     * and never released.  Use Push/Pop to manage the storage.
1307     */
1308    env->PushLocalFrame(200);
1309
1310    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
1311        env->PopLocalFrame(NULL);
1312        return -1;
1313    }
1314    env->PopLocalFrame(NULL);
1315
1316    //createJavaThread("fubar", quickTest, (void*) "hello");
1317
1318    return 0;
1319}
1320
1321AndroidRuntime* AndroidRuntime::getRuntime()
1322{
1323    return gCurRuntime;
1324}
1325
1326/**
1327 * Used by WithFramework to register native functions.
1328 */
1329extern "C"
1330jint Java_com_android_internal_util_WithFramework_registerNatives(
1331        JNIEnv* env, jclass clazz) {
1332    return register_jni_procs(gRegJNI, NELEM(gRegJNI), env);
1333}
1334
1335/**
1336 * Used by LoadClass to register native functions.
1337 */
1338extern "C"
1339jint Java_LoadClass_registerNatives(JNIEnv* env, jclass clazz) {
1340    return register_jni_procs(gRegJNI, NELEM(gRegJNI), env);
1341}
1342
1343}   // namespace android
1344