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>
18c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
1992516c84ef2a167524007a0584fb26018b5cb9c4Greg Hackmann#include <cutils/log.h>
208afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
218afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "jni.h"
228afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian#include "DdmConnection.h"
238afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
248afb7e39a83a3e31170612d562eb08508e328388Mathias Agopiannamespace android {
258afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
2663f165fd6b86d04be94d4023e845e98560504a96Keun young Parkvoid DdmConnection_start(const char* name) {
2763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    ALOGI("DdmConnection_start");
2863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection::start(name);
2963f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
30c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
318afb7e39a83a3e31170612d562eb08508e328388Mathias Agopianvoid DdmConnection::start(const char* name) {
328afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    JavaVM* vm;
338afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    JNIEnv* env;
348afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
358afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    // start a VM
368afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    JavaVMInitArgs args;
378afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    JavaVMOption opt;
388afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
398afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    opt.optionString =
408afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
418afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
428afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    args.version = JNI_VERSION_1_4;
438afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    args.options = &opt;
448afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    args.nOptions = 1;
458afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    args.ignoreUnrecognized = JNI_FALSE;
468afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
47c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
48aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom    // TODO: Should this just link against libnativehelper and use its
49aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom    // JNI_CreateJavaVM wrapper that essential does this dlopen/dlsym
50aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom    // work based on the current system default runtime?
51aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom    void* libart_dso = dlopen("libart.so", RTLD_NOW);
52aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom    ALOGE_IF(!libart_dso, "DdmConnection: %s", dlerror());
53c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
54c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    void* libandroid_runtime_dso = dlopen("libandroid_runtime.so", RTLD_NOW);
55c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGE_IF(!libandroid_runtime_dso, "DdmConnection: %s", dlerror());
56c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
57aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom    if (!libart_dso || !libandroid_runtime_dso) {
58c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        goto error;
59c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    }
60c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
61c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    jint (*JNI_CreateJavaVM)(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);
62aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom    JNI_CreateJavaVM = (typeof JNI_CreateJavaVM)dlsym(libart_dso, "JNI_CreateJavaVM");
63c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGE_IF(!JNI_CreateJavaVM, "DdmConnection: %s", dlerror());
64c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
65c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    jint (*registerNatives)(JNIEnv* env, jclass clazz);
66c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    registerNatives = (typeof registerNatives)dlsym(libandroid_runtime_dso,
67c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        "Java_com_android_internal_util_WithFramework_registerNatives");
68c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGE_IF(!registerNatives, "DdmConnection: %s", dlerror());
69c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
70c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    if (!JNI_CreateJavaVM || !registerNatives) {
71c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        goto error;
72c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    }
73c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
748afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (JNI_CreateJavaVM(&vm, &env, &args) == 0) {
758afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        jclass startClass;
768afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        jmethodID startMeth;
778afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
788afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        // register native code
79c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        if (registerNatives(env, 0) == 0) {
808afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            // set our name by calling DdmHandleAppName.setAppName()
818afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            startClass = env->FindClass("android/ddm/DdmHandleAppName");
828afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            if (startClass) {
838afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                startMeth = env->GetStaticMethodID(startClass,
841b3aeb4844fe198c1fb61064d0cec3f5ac63f7d3Mathias Agopian                        "setAppName", "(Ljava/lang/String;I)V");
858afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                if (startMeth) {
868afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                    jstring str = env->NewStringUTF(name);
871b3aeb4844fe198c1fb61064d0cec3f5ac63f7d3Mathias Agopian                    env->CallStaticVoidMethod(startClass, startMeth, str, getuid());
888afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                    env->DeleteLocalRef(str);
898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                }
908afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            }
918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
928afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            // initialize DDMS communication by calling
938afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            // DdmRegister.registerHandlers()
948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            startClass = env->FindClass("android/ddm/DdmRegister");
958afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            if (startClass) {
968afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                startMeth = env->GetStaticMethodID(startClass,
978afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                        "registerHandlers", "()V");
988afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                if (startMeth) {
998afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                    env->CallStaticVoidMethod(startClass, startMeth);
1008afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                }
1018afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            }
1028afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        }
1038afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
104c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    return;
105c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
106c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopianerror:
107c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    if (libandroid_runtime_dso) {
108c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        dlclose(libandroid_runtime_dso);
109c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    }
110aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom    if (libart_dso) {
111aefe55f0fb9e69be205497ef4fc3432d2f7a2d8bBrian Carlstrom        dlclose(libart_dso);
112c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    }
1138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian}
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1158afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian}; // namespace android
116