Merge "Camera2: Truncate JPEG images" into jb-mr1-dev
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 24f33df..bd84c66 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -822,6 +822,11 @@
                 CHECK(msg->findInt32("err", &err));
 
                 ALOGE("converter signaled error %d", err);
+
+                // Inform WifiDisplaySource of our premature death (wish).
+                sp<AMessage> notify = mNotify->dup();
+                notify->setInt32("what", kWhatSessionDead);
+                notify->post();
             }
             break;
         }
@@ -857,7 +862,7 @@
     pullLooper->start(
             false /* runOnCallingThread */,
             false /* canCallJava */,
-            PRIORITY_DEFAULT);
+            PRIORITY_AUDIO);
 
     sp<ALooper> codecLooper = new ALooper;
     codecLooper->setName("codec_looper");
@@ -865,7 +870,7 @@
     codecLooper->start(
             false /* runOnCallingThread */,
             false /* canCallJava */,
-            PRIORITY_DEFAULT);
+            PRIORITY_AUDIO);
 
     size_t trackIndex;
 
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 9ad978f..787ccc0 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -44,6 +44,7 @@
     : mNetSession(netSession),
       mClient(client),
       mSessionID(0),
+      mStopReplyID(0),
       mClientSessionID(0),
       mReaperPending(false),
       mNextCSeq(1)
@@ -232,20 +233,17 @@
             uint32_t replyID;
             CHECK(msg->senderAwaitsResponse(&replyID));
 
-            disconnectClient(OK);
+            if (mSessionID != 0 && mClientSessionID != 0) {
+                status_t err = sendM5(
+                        mClientSessionID, true /* requestShutdown */);
 
-#if REQUIRE_HDCP
-            if (mHDCP != NULL) {
-                mHDCP->shutdownAsync();
-                mHDCP.clear();
+                if (err == OK) {
+                    mStopReplyID = replyID;
+                    break;
+                }
             }
-#endif
 
-            status_t err = OK;
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
+            finishStop(replyID);
             break;
         }
 
@@ -352,13 +350,15 @@
                     if (mSetupTriggerDeferred) {
                         mSetupTriggerDeferred = false;
 
-                        sendM5(mClientSessionID);
+                        sendM5(mClientSessionID, false /* requestShutdown */);
                     }
                     break;
                 }
 
                 default:
                 {
+                    ALOGE("HDCP failure, shutting down.");
+
                     disconnectClient(-EACCES);
                     break;
                 }
@@ -499,8 +499,15 @@
     return OK;
 }
 
-status_t WifiDisplaySource::sendM5(int32_t sessionID) {
-    AString body = "wfd_trigger_method: SETUP\r\n";
+status_t WifiDisplaySource::sendM5(int32_t sessionID, bool requestShutdown) {
+    AString body = "wfd_trigger_method: ";
+    if (requestShutdown) {
+        body.append("TEARDOWN");
+    } else {
+        body.append("SETUP");
+    }
+
+    body.append("\r\n");
 
     AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
     AppendCommonResponse(&request, mNextCSeq);
@@ -639,7 +646,7 @@
     }
 #endif
 
-    return sendM5(sessionID);
+    return sendM5(sessionID, false /* requestShutdown */);
 }
 
 status_t WifiDisplaySource::onReceiveM5Response(
@@ -1073,11 +1080,33 @@
         return err;
     }
 
-    disconnectClient(UNKNOWN_ERROR);
+    if (mStopReplyID != 0) {
+        finishStop(mStopReplyID);
+        mStopReplyID = 0;
+    } else {
+        disconnectClient(UNKNOWN_ERROR);
+    }
 
     return OK;
 }
 
+void WifiDisplaySource::finishStop(uint32_t replyID) {
+    disconnectClient(OK);
+
+#if REQUIRE_HDCP
+    if (mHDCP != NULL) {
+        mHDCP->shutdownAsync();
+        mHDCP.clear();
+    }
+#endif
+
+    status_t err = OK;
+
+    sp<AMessage> response = new AMessage;
+    response->setInt32("err", err);
+    response->postReply(replyID);
+}
+
 status_t WifiDisplaySource::onGetParameterRequest(
         int32_t sessionID,
         int32_t cseq,
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index 298cb9b..1f0e375 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -91,6 +91,8 @@
     struct in_addr mInterfaceAddr;
     int32_t mSessionID;
 
+    uint32_t mStopReplyID;
+
     int32_t mClientSessionID;
 
     struct ClientInfo {
@@ -123,7 +125,7 @@
     status_t sendM1(int32_t sessionID);
     status_t sendM3(int32_t sessionID);
     status_t sendM4(int32_t sessionID);
-    status_t sendM5(int32_t sessionID);
+    status_t sendM5(int32_t sessionID, bool requestShutdown);
     status_t sendM16(int32_t sessionID);
 
     status_t onReceiveM1Response(
@@ -203,6 +205,8 @@
     // A listener is notified accordingly.
     void disconnectClient(status_t err);
 
+    void finishStop(uint32_t replyID);
+
     DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource);
 };