as a debug option SrufaceFlinger can now connect to DDMS

this is disabled by default. To enable:
  setprop debug.sf.ddms 1

this debug option requires to restart SurfaceFlinger

Change-Id: Ic2f8050b29911b55bcd21721648b6978700c277d
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index b178e49..51eb0a3 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -5,6 +5,7 @@
     Layer.cpp 								\
     LayerBase.cpp 							\
     LayerDim.cpp 							\
+    DdmConnection.cpp						\
     DisplayHardware/DisplayHardware.cpp 	\
     DisplayHardware/DisplayHardwareBase.cpp \
     DisplayHardware/HWComposer.cpp 			\
@@ -36,6 +37,9 @@
 	libui \
 	libgui
 
+# this is only needed for DDMS debugging
+LOCAL_SHARED_LIBRARIES += libdvm libandroid_runtime
+
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, corecg graphics)
 
diff --git a/services/surfaceflinger/DdmConnection.cpp b/services/surfaceflinger/DdmConnection.cpp
new file mode 100644
index 0000000..467a915
--- /dev/null
+++ b/services/surfaceflinger/DdmConnection.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android_runtime/AndroidRuntime.h>
+
+#include "jni.h"
+#include "DdmConnection.h"
+
+extern "C" jint Java_com_android_internal_util_WithFramework_registerNatives(
+        JNIEnv* env, jclass clazz);
+
+namespace android {
+
+void DdmConnection::start(const char* name) {
+    JavaVM* vm;
+    JNIEnv* env;
+
+    // start a VM
+    JavaVMInitArgs args;
+    JavaVMOption opt;
+
+    opt.optionString =
+        "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
+
+    args.version = JNI_VERSION_1_4;
+    args.options = &opt;
+    args.nOptions = 1;
+    args.ignoreUnrecognized = JNI_FALSE;
+
+    if (JNI_CreateJavaVM(&vm, &env, &args) == 0) {
+        jclass startClass;
+        jmethodID startMeth;
+
+        // register native code
+        if (Java_com_android_internal_util_WithFramework_registerNatives(env, 0) == 0) {
+            // set our name by calling DdmHandleAppName.setAppName()
+            startClass = env->FindClass("android/ddm/DdmHandleAppName");
+            if (startClass) {
+                startMeth = env->GetStaticMethodID(startClass,
+                        "setAppName", "(Ljava/lang/String;)V");
+                if (startMeth) {
+                    jstring str = env->NewStringUTF(name);
+                    env->CallStaticVoidMethod(startClass, startMeth, str);
+                    env->DeleteLocalRef(str);
+                }
+            }
+
+            // initialize DDMS communication by calling
+            // DdmRegister.registerHandlers()
+            startClass = env->FindClass("android/ddm/DdmRegister");
+            if (startClass) {
+                startMeth = env->GetStaticMethodID(startClass,
+                        "registerHandlers", "()V");
+                if (startMeth) {
+                    env->CallStaticVoidMethod(startClass, startMeth);
+                }
+            }
+        }
+    }
+}
+
+}; // namespace android
diff --git a/services/surfaceflinger/DdmConnection.h b/services/surfaceflinger/DdmConnection.h
new file mode 100644
index 0000000..91b737c
--- /dev/null
+++ b/services/surfaceflinger/DdmConnection.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SF_DDM_CONNECTION
+#define ANDROID_SF_DDM_CONNECTION
+
+namespace android {
+
+class DdmConnection {
+public:
+    static void start(const char* name);
+};
+
+}; // namespace android
+
+#endif /* ANDROID_SF_DDM_CONNECTION */
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 082effe..a68ab30 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -47,6 +47,7 @@
 
 #include "clz.h"
 #include "GLExtensions.h"
+#include "DdmConnection.h"
 #include "Layer.h"
 #include "LayerDim.h"
 #include "SurfaceFlinger.h"
@@ -90,6 +91,7 @@
         mFreezeDisplayTime(0),
         mDebugRegion(0),
         mDebugBackground(0),
+        mDebugDDMS(0),
         mDebugDisableHWC(0),
         mDebugInSwapBuffers(0),
         mLastSwapBufferTime(0),
@@ -108,13 +110,22 @@
 
     // debugging stuff...
     char value[PROPERTY_VALUE_MAX];
+
     property_get("debug.sf.showupdates", value, "0");
     mDebugRegion = atoi(value);
+
     property_get("debug.sf.showbackground", value, "0");
     mDebugBackground = atoi(value);
 
+    property_get("debug.sf.ddms", value, "0");
+    mDebugDDMS = atoi(value);
+    if (mDebugDDMS) {
+        DdmConnection::start(getServiceName());
+    }
+
     LOGI_IF(mDebugRegion,       "showupdates enabled");
     LOGI_IF(mDebugBackground,   "showbackground enabled");
+    LOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
 }
 
 SurfaceFlinger::~SurfaceFlinger()
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6f93f5b..89df0de 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -371,6 +371,7 @@
                 // don't use a lock for these, we don't care
                 int                         mDebugRegion;
                 int                         mDebugBackground;
+                int                         mDebugDDMS;
                 int                         mDebugDisableHWC;
                 volatile nsecs_t            mDebugInSwapBuffers;
                 nsecs_t                     mLastSwapBufferTime;