Merge "Fix underruns when fast track denied due to SRC" into klp-dev
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8833bd7..0dabd37 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -744,7 +744,7 @@
 
     sp<ANativeWindow> anw;
     if (bufferProducer != NULL) {
-        anw = new Surface(bufferProducer);
+        anw = new Surface(bufferProducer, true /* controlledByApp */);
         status_t err = native_window_api_connect(anw.get(),
                 NATIVE_WINDOW_API_MEDIA);
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index e1735fa..750287f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1396,6 +1396,11 @@
             uint32_t flags;
             CHECK(msg->findInt32("flags", (int32_t *)&flags));
 
+            sp<NuPlayerDriver> driver = mDriver.promote();
+            if (driver != NULL) {
+                driver->notifyFlagsChanged(flags);
+            }
+
             if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
                     && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
                 cancelPollDuration();
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 3385a19..18cf6d1 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -358,11 +358,10 @@
             uint32_t flags = 0;
 
             if (mHandler->isSeekable()) {
-                flags = FLAG_CAN_PAUSE | FLAG_CAN_SEEK;
-
-                // Seeking 10secs forward or backward is a very expensive
-                // operation for rtsp, so let's not enable that.
-                // The user can always use the seek bar.
+                flags = FLAG_CAN_PAUSE
+                        | FLAG_CAN_SEEK
+                        | FLAG_CAN_SEEK_BACKWARD
+                        | FLAG_CAN_SEEK_FORWARD;
             }
 
             notifyFlagsChanged(flags);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index bda2887..e7f6c53 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -604,7 +604,7 @@
     }
     if (params.previewCallbackFlags != (uint32_t)flag) {
 
-        if (flag != CAMERA_FRAME_CALLBACK_FLAG_NOOP) {
+        if (params.previewCallbackSurface && flag != CAMERA_FRAME_CALLBACK_FLAG_NOOP) {
             // Disable any existing preview callback window when enabling
             // preview callback flags
             res = mCallbackProcessor->setCallbackWindow(NULL);
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 060e2a2..e808bf3 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -95,7 +95,7 @@
     if (res != OK) {
         ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
                 __FUNCTION__, TClientBase::mCameraId, strerror(-res), res);
-        return NO_INIT;
+        return res;
     }
 
     res = mDevice->setNotifyCallback(this);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index b70a278..b468eb3 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1630,6 +1630,19 @@
     // If the request is the same as last, or we had triggers last time
     if (mPrevRequest != nextRequest || triggersMixedIn) {
         /**
+         * HAL workaround:
+         * Insert a dummy trigger ID if a trigger is set but no trigger ID is
+         */
+        res = addDummyTriggerIds(nextRequest);
+        if (res != OK) {
+            SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
+                    "(capture request %d, HAL device: %s (%d)",
+                    (mFrameNumber+1), strerror(-res), res);
+            cleanUpFailedRequest(request, nextRequest, outputBuffers);
+            return false;
+        }
+
+        /**
          * The request should be presorted so accesses in HAL
          *   are O(logn). Sidenote, sorting a sorted metadata is nop.
          */
@@ -2047,6 +2060,40 @@
     return OK;
 }
 
+status_t Camera3Device::RequestThread::addDummyTriggerIds(
+        const sp<CaptureRequest> &request) {
+    // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
+    static const int32_t dummyTriggerId = 1;
+    status_t res;
+
+    CameraMetadata &metadata = request->mSettings;
+
+    // If AF trigger is active, insert a dummy AF trigger ID if none already
+    // exists
+    camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
+    camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
+    if (afTrigger.count > 0 &&
+            afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
+            afId.count == 0) {
+        res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
+        if (res != OK) return res;
+    }
+
+    // If AE precapture trigger is active, insert a dummy precapture trigger ID
+    // if none already exists
+    camera_metadata_entry pcTrigger =
+            metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
+    camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
+    if (pcTrigger.count > 0 &&
+            pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
+            pcId.count == 0) {
+        res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
+                &dummyTriggerId, 1);
+        if (res != OK) return res;
+    }
+
+    return OK;
+}
 
 
 /**
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 0b3ad6e..61caf13 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -314,6 +314,10 @@
         //  restoring the old field values for those tags.
         status_t           removeTriggers(const sp<CaptureRequest> &request);
 
+        // HAL workaround: Make sure a trigger ID always exists if
+        // a trigger does
+        status_t          addDummyTriggerIds(const sp<CaptureRequest> &request);
+
         static const nsecs_t kRequestTimeout = 50e6; // 50 ms
 
         // Waits for a request, or returns NULL if times out.