| Mathias Agopian | 8afb7e3 | 2011-08-15 20:44:40 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2011 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 |  | 
| Mathias Agopian | c1d359d | 2012-08-04 20:09:03 -0700 | [diff] [blame] | 17 | #include <dlfcn.h> | 
 | 18 |  | 
| Greg Hackmann | 92516c8 | 2012-08-06 13:55:56 -0700 | [diff] [blame] | 19 | #include <cutils/log.h> | 
| Mathias Agopian | 8afb7e3 | 2011-08-15 20:44:40 -0700 | [diff] [blame] | 20 |  | 
 | 21 | #include "jni.h" | 
 | 22 | #include "DdmConnection.h" | 
 | 23 |  | 
| Mathias Agopian | 8afb7e3 | 2011-08-15 20:44:40 -0700 | [diff] [blame] | 24 | namespace android { | 
 | 25 |  | 
| Keun young Park | 63f165f | 2012-08-31 10:53:36 -0700 | [diff] [blame] | 26 | void DdmConnection_start(const char* name) { | 
 | 27 |     ALOGI("DdmConnection_start"); | 
 | 28 |     DdmConnection::start(name); | 
 | 29 | } | 
| Mathias Agopian | c1d359d | 2012-08-04 20:09:03 -0700 | [diff] [blame] | 30 |  | 
| Mathias Agopian | 8afb7e3 | 2011-08-15 20:44:40 -0700 | [diff] [blame] | 31 | void DdmConnection::start(const char* name) { | 
 | 32 |     JavaVM* vm; | 
 | 33 |     JNIEnv* env; | 
 | 34 |  | 
 | 35 |     // start a VM | 
 | 36 |     JavaVMInitArgs args; | 
 | 37 |     JavaVMOption opt; | 
 | 38 |  | 
 | 39 |     opt.optionString = | 
 | 40 |         "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y"; | 
 | 41 |  | 
 | 42 |     args.version = JNI_VERSION_1_4; | 
 | 43 |     args.options = &opt; | 
 | 44 |     args.nOptions = 1; | 
 | 45 |     args.ignoreUnrecognized = JNI_FALSE; | 
 | 46 |  | 
| Mathias Agopian | c1d359d | 2012-08-04 20:09:03 -0700 | [diff] [blame] | 47 |  | 
 | 48 |     void* libdvm_dso = dlopen("libdvm.so", RTLD_NOW); | 
 | 49 |     ALOGE_IF(!libdvm_dso, "DdmConnection: %s", dlerror()); | 
 | 50 |  | 
 | 51 |     void* libandroid_runtime_dso = dlopen("libandroid_runtime.so", RTLD_NOW); | 
 | 52 |     ALOGE_IF(!libandroid_runtime_dso, "DdmConnection: %s", dlerror()); | 
 | 53 |  | 
 | 54 |     if (!libdvm_dso || !libandroid_runtime_dso) { | 
 | 55 |         goto error; | 
 | 56 |     } | 
 | 57 |  | 
 | 58 |     jint (*JNI_CreateJavaVM)(JavaVM** p_vm, JNIEnv** p_env, void* vm_args); | 
 | 59 |     JNI_CreateJavaVM = (typeof JNI_CreateJavaVM)dlsym(libdvm_dso, "JNI_CreateJavaVM"); | 
 | 60 |     ALOGE_IF(!JNI_CreateJavaVM, "DdmConnection: %s", dlerror()); | 
 | 61 |  | 
 | 62 |     jint (*registerNatives)(JNIEnv* env, jclass clazz); | 
 | 63 |     registerNatives = (typeof registerNatives)dlsym(libandroid_runtime_dso, | 
 | 64 |         "Java_com_android_internal_util_WithFramework_registerNatives"); | 
 | 65 |     ALOGE_IF(!registerNatives, "DdmConnection: %s", dlerror()); | 
 | 66 |  | 
 | 67 |     if (!JNI_CreateJavaVM || !registerNatives) { | 
 | 68 |         goto error; | 
 | 69 |     } | 
 | 70 |  | 
| Mathias Agopian | 8afb7e3 | 2011-08-15 20:44:40 -0700 | [diff] [blame] | 71 |     if (JNI_CreateJavaVM(&vm, &env, &args) == 0) { | 
 | 72 |         jclass startClass; | 
 | 73 |         jmethodID startMeth; | 
 | 74 |  | 
 | 75 |         // register native code | 
| Mathias Agopian | c1d359d | 2012-08-04 20:09:03 -0700 | [diff] [blame] | 76 |         if (registerNatives(env, 0) == 0) { | 
| Mathias Agopian | 8afb7e3 | 2011-08-15 20:44:40 -0700 | [diff] [blame] | 77 |             // set our name by calling DdmHandleAppName.setAppName() | 
 | 78 |             startClass = env->FindClass("android/ddm/DdmHandleAppName"); | 
 | 79 |             if (startClass) { | 
 | 80 |                 startMeth = env->GetStaticMethodID(startClass, | 
 | 81 |                         "setAppName", "(Ljava/lang/String;)V"); | 
 | 82 |                 if (startMeth) { | 
 | 83 |                     jstring str = env->NewStringUTF(name); | 
 | 84 |                     env->CallStaticVoidMethod(startClass, startMeth, str); | 
 | 85 |                     env->DeleteLocalRef(str); | 
 | 86 |                 } | 
 | 87 |             } | 
 | 88 |  | 
 | 89 |             // initialize DDMS communication by calling | 
 | 90 |             // DdmRegister.registerHandlers() | 
 | 91 |             startClass = env->FindClass("android/ddm/DdmRegister"); | 
 | 92 |             if (startClass) { | 
 | 93 |                 startMeth = env->GetStaticMethodID(startClass, | 
 | 94 |                         "registerHandlers", "()V"); | 
 | 95 |                 if (startMeth) { | 
 | 96 |                     env->CallStaticVoidMethod(startClass, startMeth); | 
 | 97 |                 } | 
 | 98 |             } | 
 | 99 |         } | 
 | 100 |     } | 
| Mathias Agopian | c1d359d | 2012-08-04 20:09:03 -0700 | [diff] [blame] | 101 |     return; | 
 | 102 |  | 
 | 103 | error: | 
 | 104 |     if (libandroid_runtime_dso) { | 
 | 105 |         dlclose(libandroid_runtime_dso); | 
 | 106 |     } | 
 | 107 |     if (libdvm_dso) { | 
 | 108 |         dlclose(libdvm_dso); | 
 | 109 |     } | 
| Mathias Agopian | 8afb7e3 | 2011-08-15 20:44:40 -0700 | [diff] [blame] | 110 | } | 
 | 111 |  | 
 | 112 | }; // namespace android |