18afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian/* 28afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * Copyright (C) 2011 The Android Open Source Project 38afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * 48afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 58afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * you may not use this file except in compliance with the License. 68afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * You may obtain a copy of the License at 78afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * 88afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 98afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * 108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * Unless required by applicable law or agreed to in writing, software 118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * See the License for the specific language governing permissions and 148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian * limitations under the License. 158afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian */ 168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 17c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian#include <dlfcn.h> 18a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <sys/types.h> 19a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <unistd.h> 20c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 217823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "jni.h" 248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "DdmConnection.h" 258afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopiannamespace android { 278afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 2863f165fd6b86d04be94d4023e845e98560504a96Keun young Parkvoid DdmConnection_start(const char* name) { 2963f165fd6b86d04be94d4023e845e98560504a96Keun young Park ALOGI("DdmConnection_start"); 3063f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection::start(name); 3163f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 32c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 338afb7e39a83a3e31170612d562eb08508e328388Mathias Agopianvoid DdmConnection::start(const char* name) { 348afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian JavaVM* vm; 358afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian JNIEnv* env; 368afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 378afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian // start a VM 388afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian JavaVMInitArgs args; 398afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian JavaVMOption opt; 408afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 418afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian opt.optionString = 428afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y"; 438afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 448afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian args.version = JNI_VERSION_1_4; 458afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian args.options = &opt; 468afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian args.nOptions = 1; 478afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian args.ignoreUnrecognized = JNI_FALSE; 488afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 49c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 50aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom // TODO: Should this just link against libnativehelper and use its 51aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom // JNI_CreateJavaVM wrapper that essential does this dlopen/dlsym 52aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom // work based on the current system default runtime? 53aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom void* libart_dso = dlopen("libart.so", RTLD_NOW); 54aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom ALOGE_IF(!libart_dso, "DdmConnection: %s", dlerror()); 55c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 56c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian void* libandroid_runtime_dso = dlopen("libandroid_runtime.so", RTLD_NOW); 57c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGE_IF(!libandroid_runtime_dso, "DdmConnection: %s", dlerror()); 58c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 59aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom if (!libart_dso || !libandroid_runtime_dso) { 60c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian goto error; 61c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian } 62c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 63c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian jint (*JNI_CreateJavaVM)(JavaVM** p_vm, JNIEnv** p_env, void* vm_args); 64f10c46ef855b6410b20ebd8b1351d4d78d8eca8eDan Stoza JNI_CreateJavaVM = reinterpret_cast<decltype(JNI_CreateJavaVM)>( 65f10c46ef855b6410b20ebd8b1351d4d78d8eca8eDan Stoza dlsym(libart_dso, "JNI_CreateJavaVM")); 66c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGE_IF(!JNI_CreateJavaVM, "DdmConnection: %s", dlerror()); 67c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 68c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian jint (*registerNatives)(JNIEnv* env, jclass clazz); 69f10c46ef855b6410b20ebd8b1351d4d78d8eca8eDan Stoza registerNatives = reinterpret_cast<decltype(registerNatives)>( 70f10c46ef855b6410b20ebd8b1351d4d78d8eca8eDan Stoza dlsym(libandroid_runtime_dso, 71f10c46ef855b6410b20ebd8b1351d4d78d8eca8eDan Stoza "Java_com_android_internal_util_WithFramework_registerNatives")); 72c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGE_IF(!registerNatives, "DdmConnection: %s", dlerror()); 73c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 74c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian if (!JNI_CreateJavaVM || !registerNatives) { 75c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian goto error; 76c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian } 77c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 788afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (JNI_CreateJavaVM(&vm, &env, &args) == 0) { 798afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian jclass startClass; 808afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian jmethodID startMeth; 818afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 828afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian // register native code 83c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian if (registerNatives(env, 0) == 0) { 848afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian // set our name by calling DdmHandleAppName.setAppName() 858afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian startClass = env->FindClass("android/ddm/DdmHandleAppName"); 868afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (startClass) { 878afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian startMeth = env->GetStaticMethodID(startClass, 881b3aeb4844fe198c1fb61064d0cec3f5ac63f7d3Mathias Agopian "setAppName", "(Ljava/lang/String;I)V"); 898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (startMeth) { 908afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian jstring str = env->NewStringUTF(name); 911b3aeb4844fe198c1fb61064d0cec3f5ac63f7d3Mathias Agopian env->CallStaticVoidMethod(startClass, startMeth, str, getuid()); 928afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian env->DeleteLocalRef(str); 938afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 958afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 968afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian // initialize DDMS communication by calling 978afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian // DdmRegister.registerHandlers() 988afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian startClass = env->FindClass("android/ddm/DdmRegister"); 998afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (startClass) { 1008afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian startMeth = env->GetStaticMethodID(startClass, 1018afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian "registerHandlers", "()V"); 1028afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (startMeth) { 1038afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian env->CallStaticVoidMethod(startClass, startMeth); 1048afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1058afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1068afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 1078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 108c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian return; 109c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian 110c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopianerror: 111c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian if (libandroid_runtime_dso) { 112c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian dlclose(libandroid_runtime_dso); 113c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian } 114aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom if (libart_dso) { 115aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom dlclose(libart_dso); 116c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian } 1178afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian} 1188afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1198afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian}; // namespace android 120