error out when SurfaceTexture APIs are called while not connected

- also log a warning when freeAllBuffers is called with a non empty buffer queue
- rename freeAllBuffers to freeAllBuffersLocked

Change-Id: Idb71fdcf233b9ccae62d5a2a7c3c4bad2501d877
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 3f9e68d..f93930d 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -210,7 +210,7 @@
 
     // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for
     // all slots.
-    void freeAllBuffers();
+    void freeAllBuffersLocked();
     static bool isExternalFormat(uint32_t format);
 
 private:
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 4bbf7eb..806fbb1 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -104,7 +104,7 @@
 
 SurfaceTexture::~SurfaceTexture() {
     LOGV("SurfaceTexture::~SurfaceTexture");
-    freeAllBuffers();
+    freeAllBuffersLocked();
 }
 
 status_t SurfaceTexture::setBufferCountServerLocked(int bufferCount) {
@@ -154,6 +154,10 @@
         LOGE("setBufferCount: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
+    if (mConnectedApi == NO_CONNECTED_API) {
+        LOGE("setBufferCount: SurfaceTexture is not connected!");
+        return NO_INIT;
+    }
 
     if (bufferCount > NUM_BUFFER_SLOTS) {
         LOGE("setBufferCount: bufferCount larger than slots available");
@@ -185,7 +189,7 @@
 
     // here we're guaranteed that the client doesn't have dequeued buffers
     // and will release all of its buffer references.
-    freeAllBuffers();
+    freeAllBuffersLocked();
     mBufferCount = bufferCount;
     mClientBufferCount = bufferCount;
     mCurrentTexture = INVALID_BUFFER_SLOT;
@@ -214,6 +218,10 @@
         LOGE("requestBuffer: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
+    if (mConnectedApi == NO_CONNECTED_API) {
+        LOGE("requestBuffer: SurfaceTexture is not connected!");
+        return NO_INIT;
+    }
     if (slot < 0 || mBufferCount <= slot) {
         LOGE("requestBuffer: slot index out of range [0, %d]: %d",
                 mBufferCount, slot);
@@ -232,6 +240,10 @@
         LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
+    if (mConnectedApi == NO_CONNECTED_API) {
+        LOGE("dequeueBuffer: SurfaceTexture is not connected!");
+        return NO_INIT;
+    }
 
     if ((w && !h) || (!w && h)) {
         LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
@@ -285,7 +297,7 @@
                 ((mServerBufferCount != mBufferCount) ||
                         (mServerBufferCount < minBufferCountNeeded))) {
             // here we're guaranteed that mQueue is empty
-            freeAllBuffers();
+            freeAllBuffersLocked();
             mBufferCount = mServerBufferCount;
             if (mBufferCount < minBufferCountNeeded)
                 mBufferCount = minBufferCountNeeded;
@@ -442,6 +454,10 @@
             LOGE("queueBuffer: SurfaceTexture has been abandoned!");
             return NO_INIT;
         }
+        if (mConnectedApi == NO_CONNECTED_API) {
+            LOGE("queueBuffer: SurfaceTexture is not connected!");
+            return NO_INIT;
+        }
         if (buf < 0 || buf >= mBufferCount) {
             LOGE("queueBuffer: slot index out of range [0, %d]: %d",
                     mBufferCount, buf);
@@ -512,6 +528,10 @@
         LOGW("cancelBuffer: SurfaceTexture has been abandoned!");
         return;
     }
+    if (mConnectedApi == NO_CONNECTED_API) {
+        LOGE("cancelBuffer: SurfaceTexture is not connected!");
+        return;
+    }
 
     if (buf < 0 || buf >= mBufferCount) {
         LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
@@ -533,6 +553,10 @@
         LOGE("setCrop: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
+    if (mConnectedApi == NO_CONNECTED_API) {
+        LOGE("setCrop: SurfaceTexture is not connected!");
+        return NO_INIT;
+    }
     mNextCrop = crop;
     return OK;
 }
@@ -544,6 +568,10 @@
         LOGE("setTransform: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
+    if (mConnectedApi == NO_CONNECTED_API) {
+        LOGE("setTransform: SurfaceTexture is not connected!");
+        return NO_INIT;
+    }
     mNextTransform = transform;
     return OK;
 }
@@ -599,7 +627,7 @@
         case NATIVE_WINDOW_API_CAMERA:
             if (mConnectedApi == api) {
                 mConnectedApi = NO_CONNECTED_API;
-                freeAllBuffers();
+                freeAllBuffersLocked();
             } else {
                 LOGE("disconnect: connected to another api (cur=%d, req=%d)",
                         mConnectedApi, api);
@@ -848,7 +876,9 @@
     mFrameAvailableListener = listener;
 }
 
-void SurfaceTexture::freeAllBuffers() {
+void SurfaceTexture::freeAllBuffersLocked() {
+    LOGW_IF(!mQueue.isEmpty(),
+            "freeAllBuffersLocked called but mQueue is not empty");
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
         mSlots[i].mGraphicBuffer = 0;
         mSlots[i].mBufferState = BufferSlot::FREE;
@@ -929,7 +959,7 @@
 
 void SurfaceTexture::abandon() {
     Mutex::Autolock lock(mMutex);
-    freeAllBuffers();
+    freeAllBuffersLocked();
     mAbandoned = true;
     mCurrentTextureBuf.clear();
     mDequeueCondition.signal();