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
48c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    void* libdvm_dso = dlopen("libdvm.so", RTLD_NOW);
49c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGE_IF(!libdvm_dso, "DdmConnection: %s", dlerror());
50c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
51c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    void* libandroid_runtime_dso = dlopen("libandroid_runtime.so", RTLD_NOW);
52c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGE_IF(!libandroid_runtime_dso, "DdmConnection: %s", dlerror());
53c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
54c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    if (!libdvm_dso || !libandroid_runtime_dso) {
55c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        goto error;
56c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    }
57c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
58c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    jint (*JNI_CreateJavaVM)(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);
59c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    JNI_CreateJavaVM = (typeof JNI_CreateJavaVM)dlsym(libdvm_dso, "JNI_CreateJavaVM");
60c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGE_IF(!JNI_CreateJavaVM, "DdmConnection: %s", dlerror());
61c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
62c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    jint (*registerNatives)(JNIEnv* env, jclass clazz);
63c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    registerNatives = (typeof registerNatives)dlsym(libandroid_runtime_dso,
64c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        "Java_com_android_internal_util_WithFramework_registerNatives");
65c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGE_IF(!registerNatives, "DdmConnection: %s", dlerror());
66c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
67c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    if (!JNI_CreateJavaVM || !registerNatives) {
68c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        goto error;
69c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    }
70c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (JNI_CreateJavaVM(&vm, &env, &args) == 0) {
728afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        jclass startClass;
738afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        jmethodID startMeth;
748afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
758afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        // register native code
76c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        if (registerNatives(env, 0) == 0) {
778afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            // set our name by calling DdmHandleAppName.setAppName()
788afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            startClass = env->FindClass("android/ddm/DdmHandleAppName");
798afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            if (startClass) {
808afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                startMeth = env->GetStaticMethodID(startClass,
811b3aeb4844fe198c1fb61064d0cec3f5ac63f7d3Mathias Agopian                        "setAppName", "(Ljava/lang/String;I)V");
828afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                if (startMeth) {
838afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                    jstring str = env->NewStringUTF(name);
841b3aeb4844fe198c1fb61064d0cec3f5ac63f7d3Mathias Agopian                    env->CallStaticVoidMethod(startClass, startMeth, str, getuid());
858afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                    env->DeleteLocalRef(str);
868afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                }
878afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            }
888afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            // initialize DDMS communication by calling
908afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            // DdmRegister.registerHandlers()
918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            startClass = env->FindClass("android/ddm/DdmRegister");
928afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            if (startClass) {
938afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                startMeth = env->GetStaticMethodID(startClass,
948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                        "registerHandlers", "()V");
958afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                if (startMeth) {
968afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                    env->CallStaticVoidMethod(startClass, startMeth);
978afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian                }
988afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian            }
998afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        }
1008afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
101c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    return;
102c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian
103c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopianerror:
104c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    if (libandroid_runtime_dso) {
105c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        dlclose(libandroid_runtime_dso);
106c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    }
107c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    if (libdvm_dso) {
108c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian        dlclose(libdvm_dso);
109c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    }
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian}
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian}; // namespace android
113