Merge "Use supplicant control channel interface for p2p"
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index a6fb12e..493993d 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -275,7 +275,7 @@
         enum BufferState {
             // FREE indicates that the buffer is not currently being used and
             // will not be used in the future until it gets dequeued and
-            // subseqently queued by the client.
+            // subsequently queued by the client.
             FREE = 0,
 
             // DEQUEUED indicates that the buffer has been dequeued by the
diff --git a/include/utils/String16.h b/include/utils/String16.h
index 584f53f..360f407 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -156,7 +156,7 @@
 
 inline String16 String16::operator+(const String16& other) const
 {
-    String16 tmp;
+    String16 tmp(*this);
     tmp += other;
     return tmp;
 }
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 7ac4343..ac9b33b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -36,6 +36,10 @@
 #include <utils/Log.h>
 #include <utils/String8.h>
 
+
+#define ALLOW_DEQUEUE_CURRENT_BUFFER    false
+
+
 namespace android {
 
 // Transform matrices
@@ -294,9 +298,22 @@
             if (state == BufferSlot::DEQUEUED) {
                 dequeuedCount++;
             }
-            if (state == BufferSlot::FREE /*|| i == mCurrentTexture*/) {
-                foundSync = i;
-                if (i != mCurrentTexture) {
+
+            // if buffer is FREE it CANNOT be current
+            LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
+                    "dequeueBuffer: buffer %d is both FREE and current!", i);
+
+            if (ALLOW_DEQUEUE_CURRENT_BUFFER) {
+                if (state == BufferSlot::FREE || i == mCurrentTexture) {
+                    foundSync = i;
+                    if (i != mCurrentTexture) {
+                        found = i;
+                        break;
+                    }
+                }
+            } else {
+                if (state == BufferSlot::FREE) {
+                    foundSync = i;
                     found = i;
                     break;
                 }
@@ -325,7 +342,7 @@
         }
 
         // we're in synchronous mode and didn't find a buffer, we need to wait
-        // for for some buffers to be consumed
+        // for some buffers to be consumed
         tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
         if (tryAgain) {
             mDequeueCondition.wait(mMutex);
@@ -482,17 +499,16 @@
         mSlots[buf].mScalingMode = mNextScalingMode;
         mSlots[buf].mTimestamp = timestamp;
         mDequeueCondition.signal();
+
+        *outWidth = mDefaultWidth;
+        *outHeight = mDefaultHeight;
+        *outTransform = 0;
     } // scope for the lock
 
     // call back without lock held
     if (listener != 0) {
         listener->onFrameAvailable();
     }
-
-    *outWidth = mDefaultWidth;
-    *outHeight = mDefaultHeight;
-    *outTransform = 0;
-
     return OK;
 }
 
@@ -847,6 +863,7 @@
 void SurfaceTexture::freeAllBuffersLocked() {
     LOGW_IF(!mQueue.isEmpty(),
             "freeAllBuffersLocked called but mQueue is not empty");
+    mCurrentTexture = INVALID_BUFFER_SLOT;
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
         freeBufferLocked(i);
     }
@@ -860,6 +877,7 @@
         Fifo::iterator front(mQueue.begin());
         head = *front;
     }
+    mCurrentTexture = INVALID_BUFFER_SLOT;
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
         if (i != head) {
             freeBufferLocked(i);
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;