AndroidRuntime.cpp revision 60b62bc5c11c0bfcdf84ca8f5b2053e5747f86bc
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "AndroidRuntime"
18//#define LOG_NDEBUG 0
19
20#include <android_runtime/AndroidRuntime.h>
21#include <binder/IBinder.h>
22#include <binder/IPCThreadState.h>
23#include <binder/IServiceManager.h>
24#include <utils/Log.h>
25#include <utils/misc.h>
26#include <binder/Parcel.h>
27#include <utils/threads.h>
28#include <cutils/properties.h>
29
30#include <SkGraphics.h>
31#include <SkImageDecoder.h>
32#include <SkImageRef_GlobalPool.h>
33
34#include "jni.h"
35#include "JNIHelp.h"
36#include "JniInvocation.h"
37#include "android_util_Binder.h"
38
39#include <stdio.h>
40#include <signal.h>
41#include <sys/stat.h>
42#include <sys/types.h>
43#include <signal.h>
44#include <dirent.h>
45#include <assert.h>
46
47
48using namespace android;
49
50extern int register_android_os_Binder(JNIEnv* env);
51extern int register_android_os_Process(JNIEnv* env);
52extern int register_android_graphics_Bitmap(JNIEnv*);
53extern int register_android_graphics_BitmapFactory(JNIEnv*);
54extern int register_android_graphics_BitmapRegionDecoder(JNIEnv*);
55extern int register_android_graphics_Camera(JNIEnv* env);
56extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env);
57extern int register_android_graphics_Graphics(JNIEnv* env);
58extern int register_android_graphics_Interpolator(JNIEnv* env);
59extern int register_android_graphics_MaskFilter(JNIEnv* env);
60extern int register_android_graphics_Movie(JNIEnv* env);
61extern int register_android_graphics_NinePatch(JNIEnv*);
62extern int register_android_graphics_PathEffect(JNIEnv* env);
63extern int register_android_graphics_Shader(JNIEnv* env);
64extern int register_android_graphics_Typeface(JNIEnv* env);
65extern int register_android_graphics_YuvImage(JNIEnv* env);
66
67extern int register_com_google_android_gles_jni_EGLImpl(JNIEnv* env);
68extern int register_com_google_android_gles_jni_GLImpl(JNIEnv* env);
69extern int register_android_opengl_jni_EGL14(JNIEnv* env);
70extern int register_android_opengl_jni_EGLExt(JNIEnv* env);
71extern int register_android_opengl_jni_GLES10(JNIEnv* env);
72extern int register_android_opengl_jni_GLES10Ext(JNIEnv* env);
73extern int register_android_opengl_jni_GLES11(JNIEnv* env);
74extern int register_android_opengl_jni_GLES11Ext(JNIEnv* env);
75extern int register_android_opengl_jni_GLES20(JNIEnv* env);
76extern int register_android_opengl_jni_GLES30(JNIEnv* env);
77extern int register_android_opengl_jni_GLES31(JNIEnv* env);
78extern int register_android_opengl_jni_GLES31Ext(JNIEnv* env);
79
80extern int register_android_hardware_Camera(JNIEnv *env);
81extern int register_android_hardware_camera2_CameraMetadata(JNIEnv *env);
82extern int register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv *env);
83extern int register_android_hardware_camera2_DngCreator(JNIEnv *env);
84extern int register_android_hardware_SensorManager(JNIEnv *env);
85extern int register_android_hardware_SerialPort(JNIEnv *env);
86extern int register_android_hardware_SoundTrigger(JNIEnv *env);
87extern int register_android_hardware_UsbDevice(JNIEnv *env);
88extern int register_android_hardware_UsbDeviceConnection(JNIEnv *env);
89extern int register_android_hardware_UsbRequest(JNIEnv *env);
90
91extern int register_android_media_AudioRecord(JNIEnv *env);
92extern int register_android_media_AudioSystem(JNIEnv *env);
93extern int register_android_media_AudioTrack(JNIEnv *env);
94extern int register_android_media_JetPlayer(JNIEnv *env);
95extern int register_android_media_ToneGenerator(JNIEnv *env);
96
97extern int register_android_util_FloatMath(JNIEnv* env);
98
99namespace android {
100
101/*
102 * JNI-based registration functions.  Note these are properly contained in
103 * namespace android.
104 */
105extern int register_android_content_AssetManager(JNIEnv* env);
106extern int register_android_util_EventLog(JNIEnv* env);
107extern int register_android_util_Log(JNIEnv* env);
108extern int register_android_content_StringBlock(JNIEnv* env);
109extern int register_android_content_XmlBlock(JNIEnv* env);
110extern int register_android_emoji_EmojiFactory(JNIEnv* env);
111extern int register_android_graphics_Canvas(JNIEnv* env);
112extern int register_android_graphics_CanvasProperty(JNIEnv* env);
113extern int register_android_graphics_ColorFilter(JNIEnv* env);
114extern int register_android_graphics_DrawFilter(JNIEnv* env);
115extern int register_android_graphics_FontFamily(JNIEnv* env);
116extern int register_android_graphics_LayerRasterizer(JNIEnv*);
117extern int register_android_graphics_Matrix(JNIEnv* env);
118extern int register_android_graphics_Paint(JNIEnv* env);
119extern int register_android_graphics_Path(JNIEnv* env);
120extern int register_android_graphics_PathMeasure(JNIEnv* env);
121extern int register_android_graphics_Picture(JNIEnv*);
122extern int register_android_graphics_PorterDuff(JNIEnv* env);
123extern int register_android_graphics_Rasterizer(JNIEnv* env);
124extern int register_android_graphics_Region(JNIEnv* env);
125extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
126extern int register_android_graphics_Xfermode(JNIEnv* env);
127extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
128extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
129extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
130extern int register_android_view_RenderNode(JNIEnv* env);
131extern int register_android_view_RenderNodeAnimator(JNIEnv* env);
132extern int register_android_view_GraphicBuffer(JNIEnv* env);
133extern int register_android_view_GLES20Canvas(JNIEnv* env);
134extern int register_android_view_GLRenderer(JNIEnv* env);
135extern int register_android_view_HardwareLayer(JNIEnv* env);
136extern int register_android_view_ThreadedRenderer(JNIEnv* env);
137extern int register_android_view_Surface(JNIEnv* env);
138extern int register_android_view_SurfaceControl(JNIEnv* env);
139extern int register_android_view_SurfaceSession(JNIEnv* env);
140extern int register_android_view_TextureView(JNIEnv* env);
141extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
142extern int register_android_database_CursorWindow(JNIEnv* env);
143extern int register_android_database_SQLiteConnection(JNIEnv* env);
144extern int register_android_database_SQLiteGlobal(JNIEnv* env);
145extern int register_android_database_SQLiteDebug(JNIEnv* env);
146extern int register_android_nio_utils(JNIEnv* env);
147extern int register_android_text_format_Time(JNIEnv* env);
148extern int register_android_os_Debug(JNIEnv* env);
149extern int register_android_os_MessageQueue(JNIEnv* env);
150extern int register_android_os_Parcel(JNIEnv* env);
151extern int register_android_os_SELinux(JNIEnv* env);
152extern int register_android_os_SystemProperties(JNIEnv *env);
153extern int register_android_os_SystemClock(JNIEnv* env);
154extern int register_android_os_Trace(JNIEnv* env);
155extern int register_android_os_FileObserver(JNIEnv *env);
156extern int register_android_os_UEventObserver(JNIEnv* env);
157extern int register_android_os_MemoryFile(JNIEnv* env);
158extern int register_android_net_LocalSocketImpl(JNIEnv* env);
159extern int register_android_net_NetworkUtils(JNIEnv* env);
160extern int register_android_net_TrafficStats(JNIEnv* env);
161extern int register_android_text_AndroidCharacter(JNIEnv *env);
162extern int register_android_text_AndroidBidi(JNIEnv *env);
163extern int register_android_opengl_classes(JNIEnv *env);
164extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env);
165extern int register_android_server_Watchdog(JNIEnv* env);
166extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
167extern int register_com_android_internal_os_ZygoteInit(JNIEnv* env);
168extern int register_android_backup_BackupDataInput(JNIEnv *env);
169extern int register_android_backup_BackupDataOutput(JNIEnv *env);
170extern int register_android_backup_FileBackupHelperBase(JNIEnv *env);
171extern int register_android_backup_BackupHelperDispatcher(JNIEnv *env);
172extern int register_android_app_backup_FullBackup(JNIEnv *env);
173extern int register_android_app_ActivityThread(JNIEnv *env);
174extern int register_android_app_NativeActivity(JNIEnv *env);
175extern int register_android_media_RemoteDisplay(JNIEnv *env);
176extern int register_android_view_InputChannel(JNIEnv* env);
177extern int register_android_view_InputDevice(JNIEnv* env);
178extern int register_android_view_InputEventReceiver(JNIEnv* env);
179extern int register_android_view_InputEventSender(JNIEnv* env);
180extern int register_android_view_InputQueue(JNIEnv* env);
181extern int register_android_view_KeyCharacterMap(JNIEnv *env);
182extern int register_android_view_KeyEvent(JNIEnv* env);
183extern int register_android_view_MotionEvent(JNIEnv* env);
184extern int register_android_view_PointerIcon(JNIEnv* env);
185extern int register_android_view_VelocityTracker(JNIEnv* env);
186extern int register_android_content_res_ObbScanner(JNIEnv* env);
187extern int register_android_content_res_Configuration(JNIEnv* env);
188extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
189extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
190extern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env);
191extern int register_com_android_internal_os_Zygote(JNIEnv *env);
192extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
193
194static AndroidRuntime* gCurRuntime = NULL;
195
196static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
197{
198    if (jniThrowException(env, exc, msg) != 0)
199        assert(false);
200}
201
202/*
203 * Code written in the Java Programming Language calls here from main().
204 */
205static void com_android_internal_os_RuntimeInit_nativeFinishInit(JNIEnv* env, jobject clazz)
206{
207    gCurRuntime->onStarted();
208}
209
210static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
211{
212    gCurRuntime->onZygoteInit();
213}
214
215static void com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup(JNIEnv* env,
216        jobject clazz, jboolean exitWithoutCleanup)
217{
218    gCurRuntime->setExitWithoutCleanup(exitWithoutCleanup);
219}
220
221/*
222 * JNI registration.
223 */
224static JNINativeMethod gMethods[] = {
225    { "nativeFinishInit", "()V",
226        (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
227    { "nativeZygoteInit", "()V",
228        (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
229    { "nativeSetExitWithoutCleanup", "(Z)V",
230        (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
231};
232
233int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
234{
235    return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",
236        gMethods, NELEM(gMethods));
237}
238
239// ----------------------------------------------------------------------
240
241/*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL;
242
243AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
244        mExitWithoutCleanup(false),
245        mArgBlockStart(argBlockStart),
246        mArgBlockLength(argBlockLength)
247{
248    SkGraphics::Init();
249    // this sets our preference for 16bit images during decode
250    // in case the src is opaque and 24bit
251    SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);
252    // This cache is shared between browser native images, and java "purgeable"
253    // bitmaps. This globalpool is for images that do not either use the java
254    // heap, or are not backed by ashmem. See BitmapFactory.cpp for the key
255    // java call site.
256    SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);
257    // There is also a global font cache, but its budget is specified in code
258    // see SkFontHost_android.cpp
259
260    // Pre-allocate enough space to hold a fair number of options.
261    mOptions.setCapacity(20);
262
263    assert(gCurRuntime == NULL);        // one per process
264    gCurRuntime = this;
265}
266
267AndroidRuntime::~AndroidRuntime()
268{
269    SkGraphics::Term();
270}
271
272/*
273 * Register native methods using JNI.
274 */
275/*static*/ int AndroidRuntime::registerNativeMethods(JNIEnv* env,
276    const char* className, const JNINativeMethod* gMethods, int numMethods)
277{
278    return jniRegisterNativeMethods(env, className, gMethods, numMethods);
279}
280
281void AndroidRuntime::setArgv0(const char* argv0) {
282    strlcpy(mArgBlockStart, argv0, mArgBlockLength);
283}
284
285status_t AndroidRuntime::callMain(const String8& className, jclass clazz,
286    const Vector<String8>& args)
287{
288    JNIEnv* env;
289    jmethodID methodId;
290
291    ALOGD("Calling main entry %s", className.string());
292
293    env = getJNIEnv();
294    if (clazz == NULL || env == NULL) {
295        return UNKNOWN_ERROR;
296    }
297
298    methodId = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
299    if (methodId == NULL) {
300        ALOGE("ERROR: could not find method %s.main(String[])\n", className.string());
301        return UNKNOWN_ERROR;
302    }
303
304    /*
305     * We want to call main() with a String array with our arguments in it.
306     * Create an array and populate it.
307     */
308    jclass stringClass;
309    jobjectArray strArray;
310
311    const size_t numArgs = args.size();
312    stringClass = env->FindClass("java/lang/String");
313    strArray = env->NewObjectArray(numArgs, stringClass, NULL);
314
315    for (size_t i = 0; i < numArgs; i++) {
316        jstring argStr = env->NewStringUTF(args[i].string());
317        env->SetObjectArrayElement(strArray, i, argStr);
318    }
319
320    env->CallStaticVoidMethod(clazz, methodId, strArray);
321    return NO_ERROR;
322}
323
324/*
325 * The VM calls this through the "exit" hook.
326 */
327static void runtime_exit(int code)
328{
329    gCurRuntime->exit(code);
330}
331
332/*
333 * The VM calls this through the "vfprintf" hook.
334 *
335 * We ignore "fp" and just write the results to the log file.
336 */
337static void runtime_vfprintf(FILE* fp, const char* format, va_list ap)
338{
339    LOG_PRI_VA(ANDROID_LOG_INFO, "vm-printf", format, ap);
340}
341
342/**
343 * The VM calls this when mutex contention debugging is enabled to
344 * determine whether or not the blocked thread was a "sensitive thread"
345 * for user responsiveness/smoothess.
346 *
347 * Our policy for this is whether or not we're tracing any StrictMode
348 * events on this thread (which we might've inherited via Binder calls
349 * into us)
350 */
351static bool runtime_isSensitiveThread() {
352    IPCThreadState* state = IPCThreadState::selfOrNull();
353    return state && state->getStrictModePolicy() != 0;
354}
355
356
357/**
358 * Add VM arguments to the to-be-executed VM
359 * Stops at first non '-' argument (also stops at an argument of '--')
360 * Returns the number of args consumed
361 */
362int AndroidRuntime::addVmArguments(int argc, const char* const argv[])
363{
364    int i;
365
366    for (i = 0; i<argc; i++) {
367        if (argv[i][0] != '-') {
368            return i;
369        }
370        if (argv[i][1] == '-' && argv[i][2] == 0) {
371            return i+1;
372        }
373
374        JavaVMOption opt;
375        memset(&opt, 0, sizeof(opt));
376        opt.optionString = (char*)argv[i];
377        mOptions.add(opt);
378    }
379    return i;
380}
381
382static int hasDir(const char* dir)
383{
384    struct stat s;
385    int res = stat(dir, &s);
386    if (res == 0) {
387        return S_ISDIR(s.st_mode);
388    }
389    return 0;
390}
391
392/*
393 * Read the persistent locale.
394 */
395static void readLocale(char* language, char* region)
396{
397    char propLang[PROPERTY_VALUE_MAX], propRegn[PROPERTY_VALUE_MAX];
398
399    property_get("persist.sys.language", propLang, "");
400    property_get("persist.sys.country", propRegn, "");
401    if (*propLang == 0 && *propRegn == 0) {
402        /* Set to ro properties, default is en_US */
403        property_get("ro.product.locale.language", propLang, "en");
404        property_get("ro.product.locale.region", propRegn, "US");
405    }
406    strncat(language, propLang, 2);
407    strncat(region, propRegn, 2);
408    //ALOGD("language=%s region=%s\n", language, region);
409}
410
411/*
412 * Parse a property containing space-separated options that should be
413 * passed directly to the VM, e.g. "-Xmx32m -verbose:gc -Xregenmap".
414 *
415 * This will cut up "extraOptsBuf" as we chop it into individual options.
416 *
417 * If "quotingArg" is non-null, it is passed before each extra option in mOptions.
418 *
419 * Adds the strings, if any, to mOptions.
420 */
421void AndroidRuntime::parseExtraOpts(char* extraOptsBuf, const char* quotingArg)
422{
423    JavaVMOption opt;
424    memset(&opt, 0, sizeof(opt));
425    char* start = extraOptsBuf;
426    char* end = NULL;
427    while (*start != '\0') {
428        while (*start == ' ')                   /* skip leading whitespace */
429            start++;
430        if (*start == '\0')                     /* was trailing ws, bail */
431            break;
432
433        end = start+1;
434        while (*end != ' ' && *end != '\0')     /* find end of token */
435            end++;
436        if (*end == ' ')
437            *end++ = '\0';          /* mark end, advance to indicate more */
438
439        opt.optionString = start;
440        if (quotingArg != NULL) {
441            JavaVMOption quotingOpt;
442            quotingOpt.optionString = quotingArg;
443            mOptions.add(quotingOpt);
444        }
445        mOptions.add(opt);
446        start = end;
447    }
448}
449
450/*
451 * Start the Dalvik Virtual Machine.
452 *
453 * Various arguments, most determined by system properties, are passed in.
454 * The "mOptions" vector is updated.
455 *
456 * CAUTION: when adding options in here, be careful not to put the
457 * char buffer inside a nested scope.  Adding the buffer to the
458 * options using mOptions.add() does not copy the buffer, so if the
459 * buffer goes out of scope the option may be overwritten.  It's best
460 * to put the buffer at the top of the function so that it is more
461 * unlikely that someone will surround it in a scope at a later time
462 * and thus introduce a bug.
463 *
464 * Returns 0 on success.
465 */
466int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
467{
468    int result = -1;
469    JavaVMInitArgs initArgs;
470    JavaVMOption opt;
471    char propBuf[PROPERTY_VALUE_MAX];
472    char stackTraceFileBuf[PROPERTY_VALUE_MAX];
473    char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
474    char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];
475    char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
476    char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
477    char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
478    char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
479    char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
480    char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
481    char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
482    char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];
483    char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
484    char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX];
485    char dalvikVmLibBuf[PROPERTY_VALUE_MAX];
486    char dex2oatFlagsBuf[PROPERTY_VALUE_MAX];
487    char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX];
488    char extraOptsBuf[PROPERTY_VALUE_MAX];
489    char* stackTraceFile = NULL;
490    bool checkJni = false;
491    bool checkDexSum = false;
492    bool logStdio = false;
493    enum {
494      kEMDefault,
495      kEMIntPortable,
496      kEMIntFast,
497      kEMJitCompiler,
498    } executionMode = kEMDefault;
499    char profile_period[sizeof("-Xprofile-period:") + PROPERTY_VALUE_MAX];
500    char profile_duration[sizeof("-Xprofile-duration:") + PROPERTY_VALUE_MAX];
501    char profile_interval[sizeof("-Xprofile-interval:") + PROPERTY_VALUE_MAX];
502    char profile_backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX];
503    char langOption[sizeof("-Duser.language=") + 3];
504    char regionOption[sizeof("-Duser.region=") + 3];
505    char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
506    char jitOpBuf[sizeof("-Xjitop:") + PROPERTY_VALUE_MAX];
507    char jitMethodBuf[sizeof("-Xjitmethod:") + PROPERTY_VALUE_MAX];
508
509    property_get("dalvik.vm.checkjni", propBuf, "");
510    if (strcmp(propBuf, "true") == 0) {
511        checkJni = true;
512    } else if (strcmp(propBuf, "false") != 0) {
513        /* property is neither true nor false; fall back on kernel parameter */
514        property_get("ro.kernel.android.checkjni", propBuf, "");
515        if (propBuf[0] == '1') {
516            checkJni = true;
517        }
518    }
519
520    property_get("dalvik.vm.execution-mode", propBuf, "");
521    if (strcmp(propBuf, "int:portable") == 0) {
522        executionMode = kEMIntPortable;
523    } else if (strcmp(propBuf, "int:fast") == 0) {
524        executionMode = kEMIntFast;
525    } else if (strcmp(propBuf, "int:jit") == 0) {
526        executionMode = kEMJitCompiler;
527    }
528
529    property_get("dalvik.vm.stack-trace-file", stackTraceFileBuf, "");
530
531    property_get("dalvik.vm.check-dex-sum", propBuf, "");
532    if (strcmp(propBuf, "true") == 0) {
533        checkDexSum = true;
534    }
535
536    property_get("log.redirect-stdio", propBuf, "");
537    if (strcmp(propBuf, "true") == 0) {
538        logStdio = true;
539    }
540
541    strcpy(enableAssertBuf, "-ea:");
542    property_get("dalvik.vm.enableassertions", enableAssertBuf+4, "");
543
544    strcpy(jniOptsBuf, "-Xjniopts:");
545    property_get("dalvik.vm.jniopts", jniOptsBuf+10, "");
546
547    /* route exit() to our handler */
548    opt.extraInfo = (void*) runtime_exit;
549    opt.optionString = "exit";
550    mOptions.add(opt);
551
552    /* route fprintf() to our handler */
553    opt.extraInfo = (void*) runtime_vfprintf;
554    opt.optionString = "vfprintf";
555    mOptions.add(opt);
556
557    /* register the framework-specific "is sensitive thread" hook */
558    opt.extraInfo = (void*) runtime_isSensitiveThread;
559    opt.optionString = "sensitiveThread";
560    mOptions.add(opt);
561
562    opt.extraInfo = NULL;
563
564    /* enable verbose; standard options are { jni, gc, class } */
565    //options[curOpt++].optionString = "-verbose:jni";
566    opt.optionString = "-verbose:gc";
567    mOptions.add(opt);
568    //options[curOpt++].optionString = "-verbose:class";
569
570    /*
571     * The default starting and maximum size of the heap.  Larger
572     * values should be specified in a product property override.
573     */
574    strcpy(heapstartsizeOptsBuf, "-Xms");
575    property_get("dalvik.vm.heapstartsize", heapstartsizeOptsBuf+4, "4m");
576    opt.optionString = heapstartsizeOptsBuf;
577    mOptions.add(opt);
578    strcpy(heapsizeOptsBuf, "-Xmx");
579    property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
580    opt.optionString = heapsizeOptsBuf;
581    mOptions.add(opt);
582
583    // Increase the main thread's interpreter stack size for bug 6315322.
584    opt.optionString = "-XX:mainThreadStackSize=24K";
585    mOptions.add(opt);
586
587    // Set the max jit code cache size.  Note: size of 0 will disable the JIT.
588    strcpy(jitcodecachesizeOptsBuf, "-Xjitcodecachesize:");
589    property_get("dalvik.vm.jit.codecachesize", jitcodecachesizeOptsBuf+19,  NULL);
590    if (jitcodecachesizeOptsBuf[19] != '\0') {
591      opt.optionString = jitcodecachesizeOptsBuf;
592      mOptions.add(opt);
593    }
594
595    strcpy(heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
596    property_get("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf+20, "");
597    if (heapgrowthlimitOptsBuf[20] != '\0') {
598        opt.optionString = heapgrowthlimitOptsBuf;
599        mOptions.add(opt);
600    }
601
602    strcpy(heapminfreeOptsBuf, "-XX:HeapMinFree=");
603    property_get("dalvik.vm.heapminfree", heapminfreeOptsBuf+16, "");
604    if (heapminfreeOptsBuf[16] != '\0') {
605        opt.optionString = heapminfreeOptsBuf;
606        mOptions.add(opt);
607    }
608
609    strcpy(heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");
610    property_get("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf+16, "");
611    if (heapmaxfreeOptsBuf[16] != '\0') {
612        opt.optionString = heapmaxfreeOptsBuf;
613        mOptions.add(opt);
614    }
615
616    strcpy(heaptargetutilizationOptsBuf, "-XX:HeapTargetUtilization=");
617    property_get("dalvik.vm.heaptargetutilization", heaptargetutilizationOptsBuf+26, "");
618    if (heaptargetutilizationOptsBuf[26] != '\0') {
619        opt.optionString = heaptargetutilizationOptsBuf;
620        mOptions.add(opt);
621    }
622
623    property_get("ro.config.low_ram", propBuf, "");
624    if (strcmp(propBuf, "true") == 0) {
625      opt.optionString = "-XX:LowMemoryMode";
626      mOptions.add(opt);
627    }
628
629    strcpy(gctypeOptsBuf, "-Xgc:");
630    property_get("dalvik.vm.gctype", gctypeOptsBuf+5, "");
631    if (gctypeOptsBuf[5] != '\0') {
632        opt.optionString = gctypeOptsBuf;
633        mOptions.add(opt);
634    }
635
636    strcpy(backgroundgcOptsBuf, "-XX:BackgroundGC=");
637    property_get("dalvik.vm.backgroundgctype", backgroundgcOptsBuf+sizeof("-XX:BackgroundGC=")-1, "");
638    if (backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1] != '\0') {
639        opt.optionString = backgroundgcOptsBuf;
640        mOptions.add(opt);
641    }
642
643    /*
644     * Enable or disable dexopt features, such as bytecode verification and
645     * calculation of register maps for precise GC.
646     */
647    property_get("dalvik.vm.dexopt-flags", dexoptFlagsBuf, "");
648    if (dexoptFlagsBuf[0] != '\0') {
649        const char* opc;
650        const char* val;
651
652        opc = strstr(dexoptFlagsBuf, "v=");     /* verification */
653        if (opc != NULL) {
654            switch (*(opc+2)) {
655            case 'n':   val = "-Xverify:none";      break;
656            case 'r':   val = "-Xverify:remote";    break;
657            case 'a':   val = "-Xverify:all";       break;
658            default:    val = NULL;                 break;
659            }
660
661            if (val != NULL) {
662                opt.optionString = val;
663                mOptions.add(opt);
664            }
665        }
666
667        opc = strstr(dexoptFlagsBuf, "o=");     /* optimization */
668        if (opc != NULL) {
669            switch (*(opc+2)) {
670            case 'n':   val = "-Xdexopt:none";      break;
671            case 'v':   val = "-Xdexopt:verified";  break;
672            case 'a':   val = "-Xdexopt:all";       break;
673            case 'f':   val = "-Xdexopt:full";      break;
674            default:    val = NULL;                 break;
675            }
676
677            if (val != NULL) {
678                opt.optionString = val;
679                mOptions.add(opt);
680            }
681        }
682
683        opc = strstr(dexoptFlagsBuf, "m=y");    /* register map */
684        if (opc != NULL) {
685            opt.optionString = "-Xgenregmap";
686            mOptions.add(opt);
687
688            /* turn on precise GC while we're at it */
689            opt.optionString = "-Xgc:precise";
690            mOptions.add(opt);
691        }
692    }
693
694    /* enable debugging; set suspend=y to pause during VM init */
695    /* use android ADB transport */
696    opt.optionString =
697        "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
698    mOptions.add(opt);
699
700    ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
701    if (checkJni) {
702        /* extended JNI checking */
703        opt.optionString = "-Xcheck:jni";
704        mOptions.add(opt);
705
706        /* set a cap on JNI global references */
707        opt.optionString = "-Xjnigreflimit:2000";
708        mOptions.add(opt);
709
710        /* with -Xcheck:jni, this provides a JNI function call trace */
711        //opt.optionString = "-verbose:jni";
712        //mOptions.add(opt);
713    }
714
715    property_get("dalvik.vm.lockprof.threshold", propBuf, "");
716    if (strlen(propBuf) > 0) {
717      strcpy(lockProfThresholdBuf, "-Xlockprofthreshold:");
718      strcat(lockProfThresholdBuf, propBuf);
719      opt.optionString = lockProfThresholdBuf;
720      mOptions.add(opt);
721    }
722
723    /* Force interpreter-only mode for selected opcodes. Eg "1-0a,3c,f1-ff" */
724    property_get("dalvik.vm.jit.op", propBuf, "");
725    if (strlen(propBuf) > 0) {
726        strcpy(jitOpBuf, "-Xjitop:");
727        strcat(jitOpBuf, propBuf);
728        opt.optionString = jitOpBuf;
729        mOptions.add(opt);
730    }
731
732    /* Force interpreter-only mode for selected methods */
733    property_get("dalvik.vm.jit.method", propBuf, "");
734    if (strlen(propBuf) > 0) {
735        strcpy(jitMethodBuf, "-Xjitmethod:");
736        strcat(jitMethodBuf, propBuf);
737        opt.optionString = jitMethodBuf;
738        mOptions.add(opt);
739    }
740
741    if (executionMode == kEMIntPortable) {
742        opt.optionString = "-Xint:portable";
743        mOptions.add(opt);
744    } else if (executionMode == kEMIntFast) {
745        opt.optionString = "-Xint:fast";
746        mOptions.add(opt);
747    } else if (executionMode == kEMJitCompiler) {
748        opt.optionString = "-Xint:jit";
749        mOptions.add(opt);
750    }
751
752    if (checkDexSum) {
753        /* perform additional DEX checksum tests */
754        opt.optionString = "-Xcheckdexsum";
755        mOptions.add(opt);
756    }
757
758    if (logStdio) {
759        /* convert stdout/stderr to log messages */
760        opt.optionString = "-Xlog-stdio";
761        mOptions.add(opt);
762    }
763
764    if (enableAssertBuf[4] != '\0') {
765        /* accept "all" to mean "all classes and packages" */
766        if (strcmp(enableAssertBuf+4, "all") == 0)
767            enableAssertBuf[3] = '\0';
768        ALOGI("Assertions enabled: '%s'\n", enableAssertBuf);
769        opt.optionString = enableAssertBuf;
770        mOptions.add(opt);
771    } else {
772        ALOGV("Assertions disabled\n");
773    }
774
775    if (jniOptsBuf[10] != '\0') {
776        ALOGI("JNI options: '%s'\n", jniOptsBuf);
777        opt.optionString = jniOptsBuf;
778        mOptions.add(opt);
779    }
780
781    if (stackTraceFileBuf[0] != '\0') {
782        static const char* stfOptName = "-Xstacktracefile:";
783
784        stackTraceFile = (char*) malloc(strlen(stfOptName) +
785            strlen(stackTraceFileBuf) +1);
786        strcpy(stackTraceFile, stfOptName);
787        strcat(stackTraceFile, stackTraceFileBuf);
788        opt.optionString = stackTraceFile;
789        mOptions.add(opt);
790    }
791
792    // libart tolerates libdvm flags, but not vice versa, so only pass some options if libart.
793    property_get("persist.sys.dalvik.vm.lib.2", dalvikVmLibBuf, "libart.so");
794    bool libart = (strncmp(dalvikVmLibBuf, "libart", 6) == 0);
795
796    if (libart) {
797        // Extra options for DexClassLoader.
798        property_get("dalvik.vm.dex2oat-flags", dex2oatFlagsBuf, "");
799        parseExtraOpts(dex2oatFlagsBuf, "-Xcompiler-option");
800
801        // Extra options for boot.art/boot.oat image generation.
802        property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
803        parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option");
804    }
805
806    /* extra options; parse this late so it overrides others */
807    property_get("dalvik.vm.extra-opts", extraOptsBuf, "");
808    parseExtraOpts(extraOptsBuf, NULL);
809
810    /* Set the properties for locale */
811    {
812        strcpy(langOption, "-Duser.language=");
813        strcpy(regionOption, "-Duser.region=");
814        readLocale(langOption, regionOption);
815        opt.extraInfo = NULL;
816        opt.optionString = langOption;
817        mOptions.add(opt);
818        opt.optionString = regionOption;
819        mOptions.add(opt);
820    }
821
822    /*
823     * Set profiler options
824     */
825    if (libart) {
826      // Number of seconds during profile runs.
827      strcpy(profile_period, "-Xprofile-period:");
828      property_get("dalvik.vm.profile.period_secs", profile_period+17, "10");
829      opt.optionString = profile_period;
830      mOptions.add(opt);
831
832      // Length of each profile run (seconds).
833      strcpy(profile_duration, "-Xprofile-duration:");
834      property_get("dalvik.vm.profile.duration_secs", profile_duration+19, "30");
835      opt.optionString = profile_duration;
836      mOptions.add(opt);
837
838
839      // Polling interval during profile run (microseconds).
840      strcpy(profile_interval, "-Xprofile-interval:");
841      property_get("dalvik.vm.profile.interval_us", profile_interval+19, "10000");
842      opt.optionString = profile_interval;
843      mOptions.add(opt);
844
845      // Coefficient for period backoff.  The the period is multiplied
846      // by this value after each profile run.
847      strcpy(profile_backoff, "-Xprofile-backoff:");
848      property_get("dalvik.vm.profile.backoff_coeff", profile_backoff+18, "2.0");
849      opt.optionString = profile_backoff;
850      mOptions.add(opt);
851    }
852
853    initArgs.version = JNI_VERSION_1_4;
854    initArgs.options = mOptions.editArray();
855    initArgs.nOptions = mOptions.size();
856    initArgs.ignoreUnrecognized = JNI_FALSE;
857
858    /*
859     * Initialize the VM.
860     *
861     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
862     * If this call succeeds, the VM is ready, and we can start issuing
863     * JNI calls.
864     */
865    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
866        ALOGE("JNI_CreateJavaVM failed\n");
867        goto bail;
868    }
869
870    result = 0;
871
872bail:
873    free(stackTraceFile);
874    return result;
875}
876
877char* AndroidRuntime::toSlashClassName(const char* className)
878{
879    char* result = strdup(className);
880    for (char* cp = result; *cp != '\0'; cp++) {
881        if (*cp == '.') {
882            *cp = '/';
883        }
884    }
885    return result;
886}
887
888/*
889 * Start the Android runtime.  This involves starting the virtual machine
890 * and calling the "static void main(String[] args)" method in the class
891 * named by "className".
892 *
893 * Passes the main function two arguments, the class name and the specified
894 * options string.
895 */
896void AndroidRuntime::start(const char* className, const Vector<String8>& options)
897{
898    ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
899            className != NULL ? className : "(unknown)");
900
901    static const String8 startSystemServer("start-system-server");
902
903    /*
904     * 'startSystemServer == true' means runtime is obsolete and not run from
905     * init.rc anymore, so we print out the boot start event here.
906     */
907    for (size_t i = 0; i < options.size(); ++i) {
908        if (options[i] == startSystemServer) {
909           /* track our progress through the boot sequence */
910           const int LOG_BOOT_PROGRESS_START = 3000;
911           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
912        }
913    }
914
915    const char* rootDir = getenv("ANDROID_ROOT");
916    if (rootDir == NULL) {
917        rootDir = "/system";
918        if (!hasDir("/system")) {
919            LOG_FATAL("No root directory specified, and /android does not exist.");
920            return;
921        }
922        setenv("ANDROID_ROOT", rootDir, 1);
923    }
924
925    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
926    //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
927
928    /* start the virtual machine */
929    JniInvocation jni_invocation;
930    jni_invocation.Init(NULL);
931    JNIEnv* env;
932    if (startVm(&mJavaVM, &env) != 0) {
933        return;
934    }
935    onVmCreated(env);
936
937    /*
938     * Register android functions.
939     */
940    if (startReg(env) < 0) {
941        ALOGE("Unable to register all android natives\n");
942        return;
943    }
944
945    /*
946     * We want to call main() with a String array with arguments in it.
947     * At present we have two arguments, the class name and an option string.
948     * Create an array to hold them.
949     */
950    jclass stringClass;
951    jobjectArray strArray;
952    jstring classNameStr;
953
954    stringClass = env->FindClass("java/lang/String");
955    assert(stringClass != NULL);
956    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
957    assert(strArray != NULL);
958    classNameStr = env->NewStringUTF(className);
959    assert(classNameStr != NULL);
960    env->SetObjectArrayElement(strArray, 0, classNameStr);
961
962    for (size_t i = 0; i < options.size(); ++i) {
963        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
964        assert(optionsStr != NULL);
965        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
966    }
967
968    /*
969     * Start VM.  This thread becomes the main thread of the VM, and will
970     * not return until the VM exits.
971     */
972    char* slashClassName = toSlashClassName(className);
973    jclass startClass = env->FindClass(slashClassName);
974    if (startClass == NULL) {
975        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
976        /* keep going */
977    } else {
978        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
979            "([Ljava/lang/String;)V");
980        if (startMeth == NULL) {
981            ALOGE("JavaVM unable to find main() in '%s'\n", className);
982            /* keep going */
983        } else {
984            env->CallStaticVoidMethod(startClass, startMeth, strArray);
985
986#if 0
987            if (env->ExceptionCheck())
988                threadExitUncaughtException(env);
989#endif
990        }
991    }
992    free(slashClassName);
993
994    ALOGD("Shutting down VM\n");
995    if (mJavaVM->DetachCurrentThread() != JNI_OK)
996        ALOGW("Warning: unable to detach main thread\n");
997    if (mJavaVM->DestroyJavaVM() != 0)
998        ALOGW("Warning: VM did not shut down cleanly\n");
999}
1000
1001void AndroidRuntime::exit(int code)
1002{
1003    if (mExitWithoutCleanup) {
1004        ALOGI("VM exiting with result code %d, cleanup skipped.", code);
1005        ::_exit(code);
1006    } else {
1007        ALOGI("VM exiting with result code %d.", code);
1008        onExit(code);
1009        ::exit(code);
1010    }
1011}
1012
1013void AndroidRuntime::onVmCreated(JNIEnv* env)
1014{
1015    // If AndroidRuntime had anything to do here, we'd have done it in 'start'.
1016}
1017
1018/*
1019 * Get the JNIEnv pointer for this thread.
1020 *
1021 * Returns NULL if the slot wasn't allocated or populated.
1022 */
1023/*static*/ JNIEnv* AndroidRuntime::getJNIEnv()
1024{
1025    JNIEnv* env;
1026    JavaVM* vm = AndroidRuntime::getJavaVM();
1027    assert(vm != NULL);
1028
1029    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
1030        return NULL;
1031    return env;
1032}
1033
1034/*
1035 * Makes the current thread visible to the VM.
1036 *
1037 * The JNIEnv pointer returned is only valid for the current thread, and
1038 * thus must be tucked into thread-local storage.
1039 */
1040static int javaAttachThread(const char* threadName, JNIEnv** pEnv)
1041{
1042    JavaVMAttachArgs args;
1043    JavaVM* vm;
1044    jint result;
1045
1046    vm = AndroidRuntime::getJavaVM();
1047    assert(vm != NULL);
1048
1049    args.version = JNI_VERSION_1_4;
1050    args.name = (char*) threadName;
1051    args.group = NULL;
1052
1053    result = vm->AttachCurrentThread(pEnv, (void*) &args);
1054    if (result != JNI_OK)
1055        ALOGI("NOTE: attach of thread '%s' failed\n", threadName);
1056
1057    return result;
1058}
1059
1060/*
1061 * Detach the current thread from the set visible to the VM.
1062 */
1063static int javaDetachThread(void)
1064{
1065    JavaVM* vm;
1066    jint result;
1067
1068    vm = AndroidRuntime::getJavaVM();
1069    assert(vm != NULL);
1070
1071    result = vm->DetachCurrentThread();
1072    if (result != JNI_OK)
1073        ALOGE("ERROR: thread detach failed\n");
1074    return result;
1075}
1076
1077/*
1078 * When starting a native thread that will be visible from the VM, we
1079 * bounce through this to get the right attach/detach action.
1080 * Note that this function calls free(args)
1081 */
1082/*static*/ int AndroidRuntime::javaThreadShell(void* args) {
1083    void* start = ((void**)args)[0];
1084    void* userData = ((void **)args)[1];
1085    char* name = (char*) ((void **)args)[2];        // we own this storage
1086    free(args);
1087    JNIEnv* env;
1088    int result;
1089
1090    /* hook us into the VM */
1091    if (javaAttachThread(name, &env) != JNI_OK)
1092        return -1;
1093
1094    /* start the thread running */
1095    result = (*(android_thread_func_t)start)(userData);
1096
1097    /* unhook us */
1098    javaDetachThread();
1099    free(name);
1100
1101    return result;
1102}
1103
1104/*
1105 * This is invoked from androidCreateThreadEtc() via the callback
1106 * set with androidSetCreateThreadFunc().
1107 *
1108 * We need to create the new thread in such a way that it gets hooked
1109 * into the VM before it really starts executing.
1110 */
1111/*static*/ int AndroidRuntime::javaCreateThreadEtc(
1112                                android_thread_func_t entryFunction,
1113                                void* userData,
1114                                const char* threadName,
1115                                int32_t threadPriority,
1116                                size_t threadStackSize,
1117                                android_thread_id_t* threadId)
1118{
1119    void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
1120    int result;
1121
1122    if (!threadName)
1123        threadName = "unnamed thread";
1124
1125    args[0] = (void*) entryFunction;
1126    args[1] = userData;
1127    args[2] = (void*) strdup(threadName);   // javaThreadShell must free
1128
1129    result = androidCreateRawThreadEtc(AndroidRuntime::javaThreadShell, args,
1130        threadName, threadPriority, threadStackSize, threadId);
1131    return result;
1132}
1133
1134/*
1135 * Create a thread that is visible from the VM.
1136 *
1137 * This is called from elsewhere in the library.
1138 */
1139/*static*/ android_thread_id_t AndroidRuntime::createJavaThread(const char* name,
1140    void (*start)(void *), void* arg)
1141{
1142    android_thread_id_t threadId = 0;
1143    javaCreateThreadEtc((android_thread_func_t) start, arg, name,
1144        ANDROID_PRIORITY_DEFAULT, 0, &threadId);
1145    return threadId;
1146}
1147
1148#if 0
1149static void quickTest(void* arg)
1150{
1151    const char* str = (const char*) arg;
1152
1153    printf("In quickTest: %s\n", str);
1154}
1155#endif
1156
1157#ifdef NDEBUG
1158    #define REG_JNI(name)      { name }
1159    struct RegJNIRec {
1160        int (*mProc)(JNIEnv*);
1161    };
1162#else
1163    #define REG_JNI(name)      { name, #name }
1164    struct RegJNIRec {
1165        int (*mProc)(JNIEnv*);
1166        const char* mName;
1167    };
1168#endif
1169
1170typedef void (*RegJAMProc)();
1171
1172static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
1173{
1174    for (size_t i = 0; i < count; i++) {
1175        if (array[i].mProc(env) < 0) {
1176#ifndef NDEBUG
1177            ALOGD("----------!!! %s failed to load\n", array[i].mName);
1178#endif
1179            return -1;
1180        }
1181    }
1182    return 0;
1183}
1184
1185static void register_jam_procs(const RegJAMProc array[], size_t count)
1186{
1187    for (size_t i = 0; i < count; i++) {
1188        array[i]();
1189    }
1190}
1191
1192static const RegJNIRec gRegJNI[] = {
1193    REG_JNI(register_com_android_internal_os_RuntimeInit),
1194    REG_JNI(register_android_os_SystemClock),
1195    REG_JNI(register_android_util_EventLog),
1196    REG_JNI(register_android_util_Log),
1197    REG_JNI(register_android_util_FloatMath),
1198    REG_JNI(register_android_text_format_Time),
1199    REG_JNI(register_android_content_AssetManager),
1200    REG_JNI(register_android_content_StringBlock),
1201    REG_JNI(register_android_content_XmlBlock),
1202    REG_JNI(register_android_emoji_EmojiFactory),
1203    REG_JNI(register_android_text_AndroidCharacter),
1204    REG_JNI(register_android_text_AndroidBidi),
1205    REG_JNI(register_android_view_InputDevice),
1206    REG_JNI(register_android_view_KeyCharacterMap),
1207    REG_JNI(register_android_os_Process),
1208    REG_JNI(register_android_os_SystemProperties),
1209    REG_JNI(register_android_os_Binder),
1210    REG_JNI(register_android_os_Parcel),
1211    REG_JNI(register_android_nio_utils),
1212    REG_JNI(register_android_graphics_Graphics),
1213    REG_JNI(register_android_view_DisplayEventReceiver),
1214    REG_JNI(register_android_view_RenderNode),
1215    REG_JNI(register_android_view_RenderNodeAnimator),
1216    REG_JNI(register_android_view_GraphicBuffer),
1217    REG_JNI(register_android_view_GLES20Canvas),
1218    REG_JNI(register_android_view_GLRenderer),
1219    REG_JNI(register_android_view_HardwareLayer),
1220    REG_JNI(register_android_view_ThreadedRenderer),
1221    REG_JNI(register_android_view_Surface),
1222    REG_JNI(register_android_view_SurfaceControl),
1223    REG_JNI(register_android_view_SurfaceSession),
1224    REG_JNI(register_android_view_TextureView),
1225    REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper),
1226    REG_JNI(register_com_google_android_gles_jni_EGLImpl),
1227    REG_JNI(register_com_google_android_gles_jni_GLImpl),
1228    REG_JNI(register_android_opengl_jni_EGL14),
1229    REG_JNI(register_android_opengl_jni_EGLExt),
1230    REG_JNI(register_android_opengl_jni_GLES10),
1231    REG_JNI(register_android_opengl_jni_GLES10Ext),
1232    REG_JNI(register_android_opengl_jni_GLES11),
1233    REG_JNI(register_android_opengl_jni_GLES11Ext),
1234    REG_JNI(register_android_opengl_jni_GLES20),
1235    REG_JNI(register_android_opengl_jni_GLES30),
1236    REG_JNI(register_android_opengl_jni_GLES31),
1237    REG_JNI(register_android_opengl_jni_GLES31Ext),
1238
1239    REG_JNI(register_android_graphics_Bitmap),
1240    REG_JNI(register_android_graphics_BitmapFactory),
1241    REG_JNI(register_android_graphics_BitmapRegionDecoder),
1242    REG_JNI(register_android_graphics_Camera),
1243    REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
1244    REG_JNI(register_android_graphics_Canvas),
1245    REG_JNI(register_android_graphics_CanvasProperty),
1246    REG_JNI(register_android_graphics_ColorFilter),
1247    REG_JNI(register_android_graphics_DrawFilter),
1248    REG_JNI(register_android_graphics_FontFamily),
1249    REG_JNI(register_android_graphics_Interpolator),
1250    REG_JNI(register_android_graphics_LayerRasterizer),
1251    REG_JNI(register_android_graphics_MaskFilter),
1252    REG_JNI(register_android_graphics_Matrix),
1253    REG_JNI(register_android_graphics_Movie),
1254    REG_JNI(register_android_graphics_NinePatch),
1255    REG_JNI(register_android_graphics_Paint),
1256    REG_JNI(register_android_graphics_Path),
1257    REG_JNI(register_android_graphics_PathMeasure),
1258    REG_JNI(register_android_graphics_PathEffect),
1259    REG_JNI(register_android_graphics_Picture),
1260    REG_JNI(register_android_graphics_PorterDuff),
1261    REG_JNI(register_android_graphics_Rasterizer),
1262    REG_JNI(register_android_graphics_Region),
1263    REG_JNI(register_android_graphics_Shader),
1264    REG_JNI(register_android_graphics_SurfaceTexture),
1265    REG_JNI(register_android_graphics_Typeface),
1266    REG_JNI(register_android_graphics_Xfermode),
1267    REG_JNI(register_android_graphics_YuvImage),
1268    REG_JNI(register_android_graphics_pdf_PdfDocument),
1269    REG_JNI(register_android_graphics_pdf_PdfRenderer),
1270
1271    REG_JNI(register_android_database_CursorWindow),
1272    REG_JNI(register_android_database_SQLiteConnection),
1273    REG_JNI(register_android_database_SQLiteGlobal),
1274    REG_JNI(register_android_database_SQLiteDebug),
1275    REG_JNI(register_android_os_Debug),
1276    REG_JNI(register_android_os_FileObserver),
1277    REG_JNI(register_android_os_MessageQueue),
1278    REG_JNI(register_android_os_SELinux),
1279    REG_JNI(register_android_os_Trace),
1280    REG_JNI(register_android_os_UEventObserver),
1281    REG_JNI(register_android_net_LocalSocketImpl),
1282    REG_JNI(register_android_net_NetworkUtils),
1283    REG_JNI(register_android_net_TrafficStats),
1284    REG_JNI(register_android_os_MemoryFile),
1285    REG_JNI(register_com_android_internal_os_ZygoteInit),
1286    REG_JNI(register_com_android_internal_os_Zygote),
1287    REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
1288    REG_JNI(register_android_hardware_Camera),
1289    REG_JNI(register_android_hardware_camera2_CameraMetadata),
1290    REG_JNI(register_android_hardware_camera2_legacy_LegacyCameraDevice),
1291    REG_JNI(register_android_hardware_camera2_DngCreator),
1292    REG_JNI(register_android_hardware_SensorManager),
1293    REG_JNI(register_android_hardware_SerialPort),
1294    REG_JNI(register_android_hardware_SoundTrigger),
1295    REG_JNI(register_android_hardware_UsbDevice),
1296    REG_JNI(register_android_hardware_UsbDeviceConnection),
1297    REG_JNI(register_android_hardware_UsbRequest),
1298    REG_JNI(register_android_media_AudioRecord),
1299    REG_JNI(register_android_media_AudioSystem),
1300    REG_JNI(register_android_media_AudioTrack),
1301    REG_JNI(register_android_media_JetPlayer),
1302    REG_JNI(register_android_media_RemoteDisplay),
1303    REG_JNI(register_android_media_ToneGenerator),
1304
1305    REG_JNI(register_android_opengl_classes),
1306    REG_JNI(register_android_server_NetworkManagementSocketTagger),
1307    REG_JNI(register_android_server_Watchdog),
1308    REG_JNI(register_android_ddm_DdmHandleNativeHeap),
1309    REG_JNI(register_android_backup_BackupDataInput),
1310    REG_JNI(register_android_backup_BackupDataOutput),
1311    REG_JNI(register_android_backup_FileBackupHelperBase),
1312    REG_JNI(register_android_backup_BackupHelperDispatcher),
1313    REG_JNI(register_android_app_backup_FullBackup),
1314    REG_JNI(register_android_app_ActivityThread),
1315    REG_JNI(register_android_app_NativeActivity),
1316    REG_JNI(register_android_view_InputChannel),
1317    REG_JNI(register_android_view_InputEventReceiver),
1318    REG_JNI(register_android_view_InputEventSender),
1319    REG_JNI(register_android_view_InputQueue),
1320    REG_JNI(register_android_view_KeyEvent),
1321    REG_JNI(register_android_view_MotionEvent),
1322    REG_JNI(register_android_view_PointerIcon),
1323    REG_JNI(register_android_view_VelocityTracker),
1324
1325    REG_JNI(register_android_content_res_ObbScanner),
1326    REG_JNI(register_android_content_res_Configuration),
1327
1328    REG_JNI(register_android_animation_PropertyValuesHolder),
1329    REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
1330    REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
1331};
1332
1333/*
1334 * Register android native functions with the VM.
1335 */
1336/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
1337{
1338    /*
1339     * This hook causes all future threads created in this process to be
1340     * attached to the JavaVM.  (This needs to go away in favor of JNI
1341     * Attach calls.)
1342     */
1343    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
1344
1345    ALOGV("--- registering native functions ---\n");
1346
1347    /*
1348     * Every "register" function calls one or more things that return
1349     * a local reference (e.g. FindClass).  Because we haven't really
1350     * started the VM yet, they're all getting stored in the base frame
1351     * and never released.  Use Push/Pop to manage the storage.
1352     */
1353    env->PushLocalFrame(200);
1354
1355    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
1356        env->PopLocalFrame(NULL);
1357        return -1;
1358    }
1359    env->PopLocalFrame(NULL);
1360
1361    //createJavaThread("fubar", quickTest, (void*) "hello");
1362
1363    return 0;
1364}
1365
1366AndroidRuntime* AndroidRuntime::getRuntime()
1367{
1368    return gCurRuntime;
1369}
1370
1371/**
1372 * Used by WithFramework to register native functions.
1373 */
1374extern "C"
1375jint Java_com_android_internal_util_WithFramework_registerNatives(
1376        JNIEnv* env, jclass clazz) {
1377    return register_jni_procs(gRegJNI, NELEM(gRegJNI), env);
1378}
1379
1380/**
1381 * Used by LoadClass to register native functions.
1382 */
1383extern "C"
1384jint Java_LoadClass_registerNatives(JNIEnv* env, jclass clazz) {
1385    return register_jni_procs(gRegJNI, NELEM(gRegJNI), env);
1386}
1387
1388}   // namespace android
1389