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