Merge "SoundTrigger: allow sound model reloading" into lmp-mr1-dev
diff --git a/camera/camera2/CaptureRequest.cpp b/camera/camera2/CaptureRequest.cpp
index 57e5319..fb74c8d 100644
--- a/camera/camera2/CaptureRequest.cpp
+++ b/camera/camera2/CaptureRequest.cpp
@@ -63,9 +63,9 @@
         }
 
         // Surface.writeToParcel
-        String16 name = parcel->readString16();
-        ALOGV("%s: Read surface name = %s",
-              __FUNCTION__, String8(name).string());
+        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());
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index e09567a..d050c78 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -310,6 +310,13 @@
 }
 
 status_t NuPlayerDriver::pause() {
+    // The NuPlayerRenderer may get flushed if pause for long enough, e.g. the pause timeout tear
+    // down for audio offload mode. If that happens, the NuPlayerRenderer will no longer know the
+    // current position. So similar to seekTo, update |mPositionUs| to the pause position by calling
+    // getCurrentPosition here.
+    int msec;
+    getCurrentPosition(&msec);
+
     Mutex::Autolock autoLock(mLock);
 
     switch (mState) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 42288a3..faf115e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1039,6 +1039,7 @@
          Mutex::Autolock autoLock(mLock);
          syncQueuesDone_l();
          setPauseStartedTimeRealUs(-1);
+         setAnchorTime(-1, -1);
     }
 
     ALOGV("flushing %s", audio ? "audio" : "video");
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 71a6a73..0f11b34 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4694,15 +4694,15 @@
 
 ssize_t AudioFlinger::DuplicatingThread::threadLoop_write()
 {
+    // We convert the duplicating thread format to AUDIO_FORMAT_PCM_16_BIT
+    // for delivery downstream as needed. This in-place conversion is safe as
+    // AUDIO_FORMAT_PCM_16_BIT is smaller than any other supported format
+    // (AUDIO_FORMAT_PCM_8_BIT is not allowed here).
+    if (mFormat != AUDIO_FORMAT_PCM_16_BIT) {
+        memcpy_by_audio_format(mSinkBuffer, AUDIO_FORMAT_PCM_16_BIT,
+                               mSinkBuffer, mFormat, writeFrames * mChannelCount);
+    }
     for (size_t i = 0; i < outputTracks.size(); i++) {
-        // We convert the duplicating thread format to AUDIO_FORMAT_PCM_16_BIT
-        // for delivery downstream as needed. This in-place conversion is safe as
-        // AUDIO_FORMAT_PCM_16_BIT is smaller than any other supported format
-        // (AUDIO_FORMAT_PCM_8_BIT is not allowed here).
-        if (mFormat != AUDIO_FORMAT_PCM_16_BIT) {
-            memcpy_by_audio_format(mSinkBuffer, AUDIO_FORMAT_PCM_16_BIT,
-                    mSinkBuffer, mFormat, writeFrames * mChannelCount);
-        }
         outputTracks[i]->write(reinterpret_cast<int16_t*>(mSinkBuffer), writeFrames);
     }
     mStandby = false;