Merge "Fix MediaMetadataRetriever seek option OPTION_CLOSEST" into nyc-mr1-dev
diff --git a/camera/camera2/CaptureRequest.cpp b/camera/camera2/CaptureRequest.cpp
index fb43708..0d689a6 100644
--- a/camera/camera2/CaptureRequest.cpp
+++ b/camera/camera2/CaptureRequest.cpp
@@ -37,7 +37,7 @@
     mMetadata.clear();
     mSurfaceList.clear();
 
-    status_t err;
+    status_t err = OK;
 
     if ((err = mMetadata.readFromParcel(parcel)) != OK) {
         ALOGE("%s: Failed to read metadata from parcel", __FUNCTION__);
@@ -65,19 +65,16 @@
         }
 
         // Surface.writeToParcel
-        const char16_t* name = parcel->readString16Inplace(&len);
-        ALOGV("%s: Read surface name = %s", __FUNCTION__,
-            name != NULL ? String8(name).string() : "<null>");
-        sp<IBinder> binder(parcel->readStrongBinder());
-        ALOGV("%s: Read surface binder = %p",
-              __FUNCTION__, binder.get());
+        view::Surface surfaceShim;
+        if ((err = surfaceShim.readFromParcel(parcel)) != OK) {
+            ALOGE("%s: Failed to read output target Surface %d from parcel: %s (%d)",
+                    __FUNCTION__, i, strerror(-err), err);
+            return err;
+        }
 
         sp<Surface> surface;
-
-        if (binder != NULL) {
-            sp<IGraphicBufferProducer> gbp =
-                    interface_cast<IGraphicBufferProducer>(binder);
-            surface = new Surface(gbp);
+        if (surfaceShim.graphicBufferProducer != NULL) {
+            surface = new Surface(surfaceShim.graphicBufferProducer);
         }
 
         mSurfaceList.push_back(surface);
@@ -99,7 +96,7 @@
         return BAD_VALUE;
     }
 
-    status_t err;
+    status_t err = OK;
 
     if ((err = mMetadata.writeToParcel(parcel)) != OK) {
         return err;
@@ -111,20 +108,18 @@
     parcel->writeInt32(size);
 
     for (int32_t i = 0; i < size; ++i) {
-        sp<Surface> surface = mSurfaceList[i];
-
-        sp<IBinder> binder;
-        if (surface != 0) {
-            binder = IInterface::asBinder(surface->getIGraphicBufferProducer());
-        }
-
         // not sure if readParcelableArray does this, hard to tell from source
         parcel->writeString16(String16("android.view.Surface"));
 
         // Surface.writeToParcel
-        parcel->writeString16(String16("unknown_name"));
-        // Surface.nativeWriteToParcel
-        parcel->writeStrongBinder(binder);
+        view::Surface surfaceShim;
+        surfaceShim.name = String16("unknown_name");
+        surfaceShim.graphicBufferProducer = mSurfaceList[i]->getIGraphicBufferProducer();
+        if ((err = surfaceShim.writeToParcel(parcel)) != OK) {
+            ALOGE("%s: Failed to write output target Surface %d to parcel: %s (%d)",
+                    __FUNCTION__, i, strerror(-err), err);
+            return err;
+        }
     }
 
     parcel->writeInt32(mIsReprocess ? 1 : 0);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index c5a6e49..bd16e91 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1092,7 +1092,7 @@
     ALOGV("setNextPlayer");
     Mutex::Autolock l(mLock);
     sp<Client> c = static_cast<Client*>(player.get());
-    if (!mService->hasClient(c)) {
+    if (c != NULL && !mService->hasClient(c)) {
       return BAD_VALUE;
     }
 
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index ff5c4d4..e476424 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2160,14 +2160,19 @@
             CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
 
             dstBuffers->clear();
-            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
+            // If we're using input surface (either non-persistent created by
+            // createInputSurface(), or persistent set by setInputSurface()),
+            // give the client an empty input buffers array.
+            if (portIndex != kPortIndexInput || !mHaveInputSurface) {
+                const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
 
-            for (size_t i = 0; i < srcBuffers.size(); ++i) {
-                const BufferInfo &info = srcBuffers.itemAt(i);
+                for (size_t i = 0; i < srcBuffers.size(); ++i) {
+                    const BufferInfo &info = srcBuffers.itemAt(i);
 
-                dstBuffers->push_back(
-                        (portIndex == kPortIndexInput && mCrypto != NULL)
-                                ? info.mEncryptedData : info.mData);
+                    dstBuffers->push_back(
+                            (portIndex == kPortIndexInput && mCrypto != NULL)
+                                    ? info.mEncryptedData : info.mData);
+                }
             }
 
             (new AMessage)->postReply(replyID);
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 05dacac..8b831f0 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -3,8 +3,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-    ServiceUtilities.cpp \
-    LockWatch.cpp
+    ServiceUtilities.cpp
 
 # FIXME Move this library to frameworks/native
 LOCAL_MODULE := libserviceutility
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index c32eadd..79f4a66 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -246,9 +246,7 @@
     }
 
     mPatchPanel = new PatchPanel(this);
-    // FIXME: bug 30737845: trigger audioserver restart if main audioflinger lock
-    // is held continuously for more than 3 seconds
-    mLockWatch = new LockWatch(mLock, String8("AudioFlinger"));
+
     mMode = AUDIO_MODE_NORMAL;
 }
 
@@ -281,7 +279,6 @@
             }
         }
     }
-    mLockWatch->requestExitAndWait();
 }
 
 static const char * const audio_interfaces[] = {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e334d80..c56dcc1 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -58,7 +58,6 @@
 #include "SpdifStreamOut.h"
 #include "AudioHwDevice.h"
 #include "LinearMap.h"
-#include "LockWatch.h"
 
 #include <powermanager/IPowerManager.h>
 
@@ -631,7 +630,6 @@
     };
 
     mutable     Mutex                               mLock;
-                sp<LockWatch>                       mLockWatch;
                 // protects mClients and mNotificationClients.
                 // must be locked after mLock and ThreadBase::mLock if both must be locked
                 // avoids acquiring AudioFlinger::mLock from inside thread loop.
diff --git a/services/audioflinger/LockWatch.cpp b/services/audioflinger/LockWatch.cpp
deleted file mode 100644
index 3da7a3d..0000000
--- a/services/audioflinger/LockWatch.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#define LOG_TAG "LockWatch"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include "LockWatch.h"
-
-namespace android {
-
-void LockWatch::onFirstRef()
-{
-    run("lock watch", ANDROID_PRIORITY_URGENT_AUDIO);
-}
-
-bool LockWatch::threadLoop()
-{
-    while (!exitPending()) {
-        // we neglect previous lock time effect on period
-        usleep(mPeriodMs * 1000);
-        if (mLock.timedLock(ms2ns(mTimeOutMs)) != NO_ERROR) {
-            // FIXME: Current implementation of timedLock uses CLOCK_REALTIME which
-            // increments even during CPU suspend.  Check twice to be sure.
-            if (mLock.timedLock(ms2ns(mTimeOutMs)) != NO_ERROR) {
-                LOG_ALWAYS_FATAL("LockWatch timeout for: %s", mTag.string());
-            }
-        }
-        mLock.unlock();
-    }
-    return false;
-}
-
-}   // namespace android
-
diff --git a/services/audioflinger/LockWatch.h b/services/audioflinger/LockWatch.h
deleted file mode 100644
index 2d30217..0000000
--- a/services/audioflinger/LockWatch.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 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 LOCK_WATCH_H
-#define LOCK_WATCH_H
-
-#include <utils/String8.h>
-#include <utils/Thread.h>
-
-namespace android {
-
-// periodically checks if a mutex can be acquired and kill process otherwise
-class LockWatch : public Thread {
-
-public:
-    static const uint32_t DEFAULT_PERIOD_MS = 10000; // 10 seconds default check period
-    static const uint32_t DEFAULT_TIMEOUT_MS = 3000; // 3 seconds default lock timeout
-
-    LockWatch(Mutex& lock, const String8& tag = String8(""),
-            uint32_t periodMs = DEFAULT_PERIOD_MS, uint32_t timeoutMs = DEFAULT_TIMEOUT_MS)
-        : Thread(false /*canCallJava*/),
-          mLock(lock), mTag(tag), mPeriodMs(periodMs), mTimeOutMs(timeoutMs) {}
-
-    virtual         ~LockWatch() { }
-
-    // RefBase
-    virtual void    onFirstRef();
-
-private:
-    // Thread
-    virtual bool    threadLoop();
-
-    Mutex&          mLock;          // monitored mutex
-    String8         mTag;           // tag
-    uint32_t        mPeriodMs;      // check period in milliseconds
-    uint32_t        mTimeOutMs;     // mutex lock timeout in milliseconds
-};
-
-}   // namespace android
-
-#endif  // LOCK_WATCH_H