Merge "remove video editor from MediaProfile" into mnc-dev
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 0c18828..a3c3d3c 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -7,7 +7,7 @@
 LOCAL_MODULE:= libmedia_helper
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_C_FLAGS += -Werror -Wall
+LOCAL_C_FLAGS += -Werror -Wno-error=deprecated-declarations -Wall
 LOCAL_CLANG := true
 
 include $(BUILD_STATIC_LIBRARY)
@@ -87,7 +87,7 @@
     $(call include-path-for, audio-effects) \
     $(call include-path-for, audio-utils)
 
-LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
 LOCAL_CLANG := true
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libmedia/IResourceManagerService.cpp b/media/libmedia/IResourceManagerService.cpp
index 7cb0f79..6902e99 100644
--- a/media/libmedia/IResourceManagerService.cpp
+++ b/media/libmedia/IResourceManagerService.cpp
@@ -48,7 +48,7 @@
 template <typename T>
 static void readFromParcel(const Parcel &data, Vector<T> *items) {
     size_t size = (size_t)data.readUint32();
-    for (size_t i = 0; i < size; i++) {
+    for (size_t i = 0; i < size && data.dataAvail() > 0; i++) {
         T item;
         item.readFromParcel(data);
         items->add(item);
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 2c4e719..b52db97 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -54,7 +54,7 @@
     $(TOP)/frameworks/native/include/media/openmax                  \
     $(TOP)/external/tremolo/Tremolo                                 \
 
-LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
 LOCAL_CLANG := true
 
 LOCAL_MODULE:= libmediaplayerservice
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 88a7745..64d172e 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -56,7 +56,7 @@
       mVideoLastDequeueTimeUs(0),
       mFetchSubtitleDataGeneration(0),
       mFetchTimedTextDataGeneration(0),
-      mDurationUs(0ll),
+      mDurationUs(-1ll),
       mAudioIsVorbis(false),
       mIsWidevine(false),
       mIsSecure(false),
@@ -324,6 +324,10 @@
     return INVALID_OPERATION;
 }
 
+bool NuPlayer::GenericSource::isStreaming() const {
+    return mIsStreaming;
+}
+
 NuPlayer::GenericSource::~GenericSource() {
     if (mLooper != NULL) {
         mLooper->unregisterHandler(id());
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 0a75e4c..dc85d2d 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -75,6 +75,8 @@
 
     virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers);
 
+    virtual bool isStreaming() const;
+
 protected:
     virtual ~GenericSource();
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index a79858c..8760cbb 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -834,7 +834,7 @@
                 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
                 const bool hasVideo = (videoFormat != NULL);
                 const bool canOffload = canOffloadStream(
-                        audioMeta, hasVideo, true /* is_streaming */, streamType);
+                        audioMeta, hasVideo, mSource->isStreaming(), streamType);
                 if (canOffload) {
                     if (!mOffloadAudio) {
                         mRenderer->signalEnableOffloadAudio();
@@ -1107,7 +1107,7 @@
                     audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
                     const bool hasVideo = (videoFormat != NULL);
                     const bool canOffload = canOffloadStream(
-                            audioMeta, hasVideo, true /* is_streaming */, streamType);
+                            audioMeta, hasVideo, mSource->isStreaming(), streamType);
                     if (canOffload) {
                         mRenderer->signalEnableOffloadAudio();
                         sp<AMessage> format = mSource->getFormat(true /*audio*/);
@@ -1288,8 +1288,7 @@
     sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
 
     mOffloadAudio =
-        canOffloadStream(audioMeta, (videoFormat != NULL),
-                         true /* is_streaming */, streamType);
+        canOffloadStream(audioMeta, (videoFormat != NULL), mSource->isStreaming(), streamType);
     if (mOffloadAudio) {
         flags |= Renderer::FLAG_OFFLOAD_AUDIO;
     }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index ef1ba13..11a6a9f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -118,6 +118,10 @@
         return false;
     }
 
+    virtual bool isStreaming() const {
+        return true;
+    }
+
 protected:
     virtual ~Source() {}
 
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 6010558..337068e 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -124,7 +124,9 @@
         libdl \
         libRScpp \
 
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall -DENABLE_STAGEFRIGHT_EXPERIMENTS
+LOCAL_CFLAGS += -Wno-multichar -Werror -Wno-error=deprecated-declarations -Wall \
+        -DENABLE_STAGEFRIGHT_EXPERIMENTS
+
 LOCAL_CLANG := true
 
 LOCAL_MODULE:= libstagefright
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 6afac74..449d195 100755
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -1188,7 +1188,10 @@
         BufferInfo *outputBufferInfo = *outQueue.begin();
         OMX_BUFFERHEADERTYPE *outputBufferHeader = outputBufferInfo->mHeader;
 
-        if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+        if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS &&
+                inputBufferHeader->nFilledLen == 0) {
+            mSawInputEOS = true;
+
             inQueue.erase(inQueue.begin());
             inputBufferInfo->mOwnedByUs = false;
             notifyEmptyBufferDone(inputBufferHeader);
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 753eb28..3dc1f7f 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -169,10 +169,8 @@
       mNodeID(0),
       mHandle(NULL),
       mObserver(observer),
-      mDying(false)
-#ifdef __LP64__
-      , mBufferIDCount(0)
-#endif
+      mDying(false),
+      mBufferIDCount(0)
 {
     mName = ADebug::GetDebugName(name);
     DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug");
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 8bccb47..949c91d 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -335,13 +335,21 @@
 
     // TODO: handle configuration of effects replacing track process
     channelMask = thread->channelMask();
+    mConfig.outputCfg.channels = channelMask;
 
     if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
         mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
     } else {
         mConfig.inputCfg.channels = channelMask;
+        // TODO: Update this logic when multichannel effects are implemented.
+        // For offloaded tracks consider mono output as stereo for proper effect initialization
+        if (channelMask == AUDIO_CHANNEL_OUT_MONO) {
+            mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+            mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+            ALOGV("Overriding effect input and output as STEREO");
+        }
     }
-    mConfig.outputCfg.channels = channelMask;
+
     mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
     mConfig.inputCfg.samplingRate = thread->sampleRate();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9f08851..7809eff 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -356,13 +356,47 @@
         AUDIO_DEVICE_OUT_SPEAKER,           "SPEAKER",
         AUDIO_DEVICE_OUT_WIRED_HEADSET,     "WIRED_HEADSET",
         AUDIO_DEVICE_OUT_WIRED_HEADPHONE,   "WIRED_HEADPHONE",
+        AUDIO_DEVICE_OUT_BLUETOOTH_SCO,     "BLUETOOTH_SCO",
+        AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,     "BLUETOOTH_SCO_HEADSET",
+        AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,      "BLUETOOTH_SCO_CARKIT",
+        AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,            "BLUETOOTH_A2DP",
+        AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, "BLUETOOTH_A2DP_HEADPHONES",
+        AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER,    "BLUETOOTH_A2DP_SPEAKER",
+        AUDIO_DEVICE_OUT_AUX_DIGITAL,       "AUX_DIGITAL",
+        AUDIO_DEVICE_OUT_HDMI,              "HDMI",
+        AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, "ANLG_DOCK_HEADSET",
+        AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, "DGTL_DOCK_HEADSET",
+        AUDIO_DEVICE_OUT_USB_ACCESSORY,     "USB_ACCESSORY",
+        AUDIO_DEVICE_OUT_USB_DEVICE,        "USB_DEVICE",
         AUDIO_DEVICE_OUT_TELEPHONY_TX,      "TELEPHONY_TX",
+        AUDIO_DEVICE_OUT_LINE,              "LINE",
+        AUDIO_DEVICE_OUT_HDMI_ARC,          "HDMI_ARC",
+        AUDIO_DEVICE_OUT_SPDIF,             "SPDIF",
+        AUDIO_DEVICE_OUT_FM,                "FM",
+        AUDIO_DEVICE_OUT_AUX_LINE,          "AUX_LINE",
+        AUDIO_DEVICE_OUT_SPEAKER_SAFE,      "SPEAKER_SAFE",
         AUDIO_DEVICE_NONE,                  "NONE",         // must be last
     }, mappingsIn[] = {
+        AUDIO_DEVICE_IN_COMMUNICATION,      "COMMUNICATION",
+        AUDIO_DEVICE_IN_AMBIENT,            "AMBIENT",
         AUDIO_DEVICE_IN_BUILTIN_MIC,        "BUILTIN_MIC",
+        AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,  "BLUETOOTH_SCO_HEADSET",
         AUDIO_DEVICE_IN_WIRED_HEADSET,      "WIRED_HEADSET",
+        AUDIO_DEVICE_IN_AUX_DIGITAL,        "AUX_DIGITAL",
         AUDIO_DEVICE_IN_VOICE_CALL,         "VOICE_CALL",
+        AUDIO_DEVICE_IN_TELEPHONY_RX,       "TELEPHONY_RX",
+        AUDIO_DEVICE_IN_BACK_MIC,           "BACK_MIC",
         AUDIO_DEVICE_IN_REMOTE_SUBMIX,      "REMOTE_SUBMIX",
+        AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET,  "ANLG_DOCK_HEADSET",
+        AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET,  "DGTL_DOCK_HEADSET",
+        AUDIO_DEVICE_IN_USB_ACCESSORY,      "USB_ACCESSORY",
+        AUDIO_DEVICE_IN_USB_DEVICE,         "USB_DEVICE",
+        AUDIO_DEVICE_IN_FM_TUNER,           "FM_TUNER",
+        AUDIO_DEVICE_IN_TV_TUNER,           "TV_TUNER",
+        AUDIO_DEVICE_IN_LINE,               "LINE",
+        AUDIO_DEVICE_IN_SPDIF,              "SPDIF",
+        AUDIO_DEVICE_IN_BLUETOOTH_A2DP,     "BLUETOOTH_A2DP",
+        AUDIO_DEVICE_IN_LOOPBACK,           "LOOPBACK",
         AUDIO_DEVICE_NONE,                  "NONE",         // must be last
     };
     String8 result;
@@ -1404,7 +1438,7 @@
         mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
         mMixerStatus(MIXER_IDLE),
         mMixerStatusIgnoringFastTracks(MIXER_IDLE),
-        standbyDelay(AudioFlinger::mStandbyTimeInNsecs),
+        mStandbyDelayNs(AudioFlinger::mStandbyTimeInNsecs),
         mBytesRemaining(0),
         mCurrentWriteLength(0),
         mUseAsyncWrite(false),
@@ -2458,9 +2492,9 @@
 /*
 The derived values that are cached:
  - mSinkBufferSize from frame count * frame size
- - activeSleepTime from activeSleepTimeUs()
- - idleSleepTime from idleSleepTimeUs()
- - standbyDelay from mActiveSleepTimeUs (DIRECT only)
+ - mActiveSleepTimeUs from activeSleepTimeUs()
+ - mIdleSleepTimeUs from idleSleepTimeUs()
+ - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only)
  - maxPeriod from frame count and sample rate (MIXER only)
 
 The parameters that affect these derived values are:
@@ -2477,8 +2511,8 @@
 void AudioFlinger::PlaybackThread::cacheParameters_l()
 {
     mSinkBufferSize = mNormalFrameCount * mFrameSize;
-    activeSleepTime = activeSleepTimeUs();
-    idleSleepTime = idleSleepTimeUs();
+    mActiveSleepTimeUs = activeSleepTimeUs();
+    mIdleSleepTimeUs = idleSleepTimeUs();
 }
 
 void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
@@ -2645,7 +2679,7 @@
 {
     Vector< sp<Track> > tracksToRemove;
 
-    standbyTime = systemTime();
+    mStandbyTimeNs = systemTime();
 
     // MIXER
     nsecs_t lastWarning = 0;
@@ -2657,7 +2691,7 @@
     int lastGeneration = 0;
 
     cacheParameters_l();
-    sleepTime = idleSleepTime;
+    mSleepTimeUs = mIdleSleepTimeUs;
 
     if (mType == MIXER) {
         sleepTimeShift = 0;
@@ -2736,12 +2770,12 @@
                 if (released) {
                     acquireWakeLock_l();
                 }
-                standbyTime = systemTime() + standbyDelay;
-                sleepTime = 0;
+                mStandbyTimeNs = systemTime() + mStandbyDelayNs;
+                mSleepTimeUs = 0;
 
                 continue;
             }
-            if ((!mActiveTracks.size() && systemTime() > standbyTime) ||
+            if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) ||
                                    isSuspended()) {
                 // put audio hardware into standby after short delay
                 if (shouldStandby_l()) {
@@ -2776,8 +2810,8 @@
                     mBytesRemaining = 0;
                     checkSilentMode_l();
 
-                    standbyTime = systemTime() + standbyDelay;
-                    sleepTime = idleSleepTime;
+                    mStandbyTimeNs = systemTime() + mStandbyDelayNs;
+                    mSleepTimeUs = mIdleSleepTimeUs;
                     if (mType == MIXER) {
                         sleepTimeShift = 0;
                     }
@@ -2808,15 +2842,15 @@
                 threadLoop_mix();
             } else if ((mMixerStatus != MIXER_DRAIN_TRACK)
                         && (mMixerStatus != MIXER_DRAIN_ALL)) {
-                // threadLoop_sleepTime sets sleepTime to 0 if data
+                // threadLoop_sleepTime sets mSleepTimeUs to 0 if data
                 // must be written to HAL
                 threadLoop_sleepTime();
-                if (sleepTime == 0) {
+                if (mSleepTimeUs == 0) {
                     mCurrentWriteLength = mSinkBufferSize;
                 }
             }
             // Either threadLoop_mix() or threadLoop_sleepTime() should have set
-            // mMixerBuffer with data if mMixerBufferValid is true and sleepTime == 0.
+            // mMixerBuffer with data if mMixerBufferValid is true and mSleepTimeUs == 0.
             // Merge mMixerBuffer data into mEffectBuffer (if any effects are valid)
             // or mSinkBuffer (if there are no effects).
             //
@@ -2824,7 +2858,7 @@
             // support higher precision, this needs to move.
             //
             // mMixerBufferValid is only set true by MixerThread::prepareTracks_l().
-            // TODO use sleepTime == 0 as an additional condition.
+            // TODO use mSleepTimeUs == 0 as an additional condition.
             if (mMixerBufferValid) {
                 void *buffer = mEffectBufferValid ? mEffectBuffer : mSinkBuffer;
                 audio_format_t format = mEffectBufferValid ? mEffectBufferFormat : mFormat;
@@ -2835,14 +2869,14 @@
 
             mBytesRemaining = mCurrentWriteLength;
             if (isSuspended()) {
-                sleepTime = suspendSleepTimeUs();
+                mSleepTimeUs = suspendSleepTimeUs();
                 // simulate write to HAL when suspended
                 mBytesWritten += mSinkBufferSize;
                 mBytesRemaining = 0;
             }
 
             // only process effects if we're going to write
-            if (sleepTime == 0 && mType != OFFLOAD) {
+            if (mSleepTimeUs == 0 && mType != OFFLOAD) {
                 for (size_t i = 0; i < effectChains.size(); i ++) {
                     effectChains[i]->process_l();
                 }
@@ -2861,7 +2895,7 @@
         // Only if the Effects buffer is enabled and there is data in the
         // Effects buffer (buffer valid), we need to
         // copy into the sink buffer.
-        // TODO use sleepTime == 0 as an additional condition.
+        // TODO use mSleepTimeUs == 0 as an additional condition.
         if (mEffectBufferValid) {
             //ALOGV("writing effect buffer to sink buffer format %#x", mFormat);
             memcpy_by_audio_format(mSinkBuffer, mFormat, mEffectBuffer, mEffectBufferFormat,
@@ -2872,8 +2906,8 @@
         unlockEffectChains(effectChains);
 
         if (!waitingAsyncCallback()) {
-            // sleepTime == 0 means we must write to audio hardware
-            if (sleepTime == 0) {
+            // mSleepTimeUs == 0 means we must write to audio hardware
+            if (mSleepTimeUs == 0) {
                 if (mBytesRemaining) {
                     ssize_t ret = threadLoop_write();
                     if (ret < 0) {
@@ -2903,7 +2937,7 @@
 
             } else {
                 ATRACE_BEGIN("sleep");
-                usleep(sleepTime);
+                usleep(mSleepTimeUs);
                 ATRACE_END();
             }
         }
@@ -3499,11 +3533,11 @@
     // Only increase sleep time if the mixer is ready for two consecutive times to avoid
     // that a steady state of alternating ready/not ready conditions keeps the sleep time
     // such that we would underrun the audio HAL.
-    if ((sleepTime == 0) && (sleepTimeShift > 0)) {
+    if ((mSleepTimeUs == 0) && (sleepTimeShift > 0)) {
         sleepTimeShift--;
     }
-    sleepTime = 0;
-    standbyTime = systemTime() + standbyDelay;
+    mSleepTimeUs = 0;
+    mStandbyTimeNs = systemTime() + mStandbyDelayNs;
     //TODO: delay standby when effects have a tail
 
 }
@@ -3512,11 +3546,11 @@
 {
     // If no tracks are ready, sleep once for the duration of an output
     // buffer size, then write 0s to the output
-    if (sleepTime == 0) {
+    if (mSleepTimeUs == 0) {
         if (mMixerStatus == MIXER_TRACKS_ENABLED) {
-            sleepTime = activeSleepTime >> sleepTimeShift;
-            if (sleepTime < kMinThreadSleepTimeUs) {
-                sleepTime = kMinThreadSleepTimeUs;
+            mSleepTimeUs = mActiveSleepTimeUs >> sleepTimeShift;
+            if (mSleepTimeUs < kMinThreadSleepTimeUs) {
+                mSleepTimeUs = kMinThreadSleepTimeUs;
             }
             // reduce sleep time in case of consecutive application underruns to avoid
             // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer
@@ -3526,7 +3560,7 @@
                 sleepTimeShift++;
             }
         } else {
-            sleepTime = idleSleepTime;
+            mSleepTimeUs = mIdleSleepTimeUs;
         }
     } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) {
         // clear out mMixerBuffer or mSinkBuffer, to ensure buffers are cleared
@@ -3536,7 +3570,7 @@
         } else {
             memset(mSinkBuffer, 0, mSinkBufferSize);
         }
-        sleepTime = 0;
+        mSleepTimeUs = 0;
         ALOGV_IF(mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED),
                 "anticipated start");
     }
@@ -4475,7 +4509,7 @@
                 track->mRetryCount = kMaxTrackRetriesDirect;
                 mActiveTrack = t;
                 mixerStatus = MIXER_TRACKS_READY;
-                if (usesHwAvSync() && mHwPaused) {
+                if (mHwPaused) {
                     doHwResume = true;
                     mHwPaused = false;
                 }
@@ -4527,7 +4561,7 @@
                     android_atomic_or(CBLK_DISABLED, &cblk->mFlags);
                 } else if (last) {
                     mixerStatus = MIXER_TRACKS_ENABLED;
-                    if (usesHwAvSync() && !mHwPaused && !mStandby) {
+                    if (mHwSupportsPause && !mHwPaused && !mStandby) {
                         doHwPause = true;
                         mHwPaused = true;
                     }
@@ -4585,8 +4619,8 @@
         mActiveTrack->releaseBuffer(&buffer);
     }
     mCurrentWriteLength = curBuf - (int8_t *)mSinkBuffer;
-    sleepTime = 0;
-    standbyTime = systemTime() + standbyDelay;
+    mSleepTimeUs = 0;
+    mStandbyTimeNs = systemTime() + mStandbyDelayNs;
     mActiveTrack.clear();
 }
 
@@ -4594,18 +4628,18 @@
 {
     // do not write to HAL when paused
     if (mHwPaused || (usesHwAvSync() && mStandby)) {
-        sleepTime = idleSleepTime;
+        mSleepTimeUs = mIdleSleepTimeUs;
         return;
     }
-    if (sleepTime == 0) {
+    if (mSleepTimeUs == 0) {
         if (mMixerStatus == MIXER_TRACKS_ENABLED) {
-            sleepTime = activeSleepTime;
+            mSleepTimeUs = mActiveSleepTimeUs;
         } else {
-            sleepTime = idleSleepTime;
+            mSleepTimeUs = mIdleSleepTimeUs;
         }
     } else if (mBytesWritten != 0 && audio_is_linear_pcm(mFormat)) {
         memset(mSinkBuffer, 0, mFrameCount * mFrameSize);
-        sleepTime = 0;
+        mSleepTimeUs = 0;
     }
 }
 
@@ -4641,7 +4675,7 @@
                            mTracks[mTracks.size() - 1]->mState == TrackBase::IDLE;
     }
 
-    return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused && !trackStopped));
+    return !mStandby && !(trackPaused || (mHwPaused && !trackStopped));
 }
 
 // getTrackName_l() must be called with ThreadBase::mLock held
@@ -4746,11 +4780,11 @@
     // hardware resources as soon as possible
     // no delay on outputs with HW A/V sync
     if (usesHwAvSync()) {
-        standbyDelay = 0;
-    } else if (audio_is_linear_pcm(mFormat)) {
-        standbyDelay = microseconds(activeSleepTime*2);
+        mStandbyDelayNs = 0;
+    } else if ((mType == OFFLOAD) && !audio_is_linear_pcm(mFormat)) {
+        mStandbyDelayNs = kOffloadStandbyDelayNs;
     } else {
-        standbyDelay = kOffloadStandbyDelayNs;
+        mStandbyDelayNs = microseconds(mActiveSleepTimeUs*2);
     }
 }
 
@@ -4930,7 +4964,7 @@
         if (track->isPausing()) {
             track->setPaused();
             if (last) {
-                if (!mHwPaused) {
+                if (mHwSupportsPause && !mHwPaused) {
                     doHwPause = true;
                     mHwPaused = true;
                 }
@@ -4966,7 +5000,7 @@
                     // resume an interrupted write
                 }
                 // enable write to audio HAL
-                sleepTime = 0;
+                mSleepTimeUs = 0;
 
                 // Do not handle new data in this iteration even if track->framesReady()
                 mixerStatus = MIXER_TRACKS_ENABLED;
@@ -5026,8 +5060,8 @@
                         // do not modify drain sequence if we are already draining. This happens
                         // when resuming from pause after drain.
                         if ((mDrainSequence & 1) == 0) {
-                            sleepTime = 0;
-                            standbyTime = systemTime() + standbyDelay;
+                            mSleepTimeUs = 0;
+                            mStandbyTimeNs = systemTime() + mStandbyDelayNs;
                             mixerStatus = MIXER_DRAIN_TRACK;
                             mDrainSequence += 2;
                         }
@@ -5169,19 +5203,19 @@
             memset(mSinkBuffer, 0, mSinkBufferSize);
         }
     }
-    sleepTime = 0;
+    mSleepTimeUs = 0;
     writeFrames = mNormalFrameCount;
     mCurrentWriteLength = mSinkBufferSize;
-    standbyTime = systemTime() + standbyDelay;
+    mStandbyTimeNs = systemTime() + mStandbyDelayNs;
 }
 
 void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()
 {
-    if (sleepTime == 0) {
+    if (mSleepTimeUs == 0) {
         if (mMixerStatus == MIXER_TRACKS_ENABLED) {
-            sleepTime = activeSleepTime;
+            mSleepTimeUs = mActiveSleepTimeUs;
         } else {
-            sleepTime = idleSleepTime;
+            mSleepTimeUs = mIdleSleepTimeUs;
         }
     } else if (mBytesWritten != 0) {
         if (mMixerStatus == MIXER_TRACKS_ENABLED) {
@@ -5191,7 +5225,7 @@
             // flush remaining overflow buffers in output tracks
             writeFrames = 0;
         }
-        sleepTime = 0;
+        mSleepTimeUs = 0;
     }
 }
 
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index aa20525..07c226e 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -755,14 +755,14 @@
     bool                            mInWrite;
 
     // FIXME rename these former local variables of threadLoop to standard "m" names
-    nsecs_t                         standbyTime;
+    nsecs_t                         mStandbyTimeNs;
     size_t                          mSinkBufferSize;
 
     // cached copies of activeSleepTimeUs() and idleSleepTimeUs() made by cacheParameters_l()
-    uint32_t                        activeSleepTime;
-    uint32_t                        idleSleepTime;
+    uint32_t                        mActiveSleepTimeUs;
+    uint32_t                        mIdleSleepTimeUs;
 
-    uint32_t                        sleepTime;
+    uint32_t                        mSleepTimeUs;
 
     // mixer status returned by prepareTracks_l()
     mixer_state                     mMixerStatus; // current cycle
@@ -775,7 +775,7 @@
     uint32_t                        sleepTimeShift;
 
     // same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value
-    nsecs_t                         standbyDelay;
+    nsecs_t                         mStandbyDelayNs;
 
     // MIXER only
     nsecs_t                         maxPeriod;
diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp
index c662853..2f0117d 100644
--- a/services/camera/libcameraservice/common/CameraModule.cpp
+++ b/services/camera/libcameraservice/common/CameraModule.cpp
@@ -31,7 +31,7 @@
 
     // Keys added in HAL3.3
     if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
-        const size_t NUM_DERIVED_KEYS_HAL3_3 = 3;
+        const size_t NUM_DERIVED_KEYS_HAL3_3 = 5;
         Vector<uint8_t> controlModes;
         uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
         chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/1);
@@ -80,6 +80,29 @@
 
         chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes);
 
+        entry = chars.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
+        // HAL3.2 devices passing existing CTS test should all support all LSC modes and LSC map
+        bool lensShadingModeSupported = false;
+        if (entry.count > 0) {
+            for (size_t i = 0; i < entry.count; i++) {
+                if (entry.data.i32[i] == ANDROID_SHADING_MODE) {
+                    lensShadingModeSupported = true;
+                    break;
+                }
+            }
+        }
+        Vector<uint8_t> lscModes;
+        Vector<uint8_t> lscMapModes;
+        lscModes.push(ANDROID_SHADING_MODE_FAST);
+        lscModes.push(ANDROID_SHADING_MODE_HIGH_QUALITY);
+        lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
+        if (lensShadingModeSupported) {
+            lscModes.push(ANDROID_SHADING_MODE_OFF);
+            lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON);
+        }
+        chars.update(ANDROID_SHADING_AVAILABLE_MODES, lscModes);
+        chars.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, lscMapModes);
+
         entry = chars.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
         Vector<int32_t> availableCharsKeys;
         availableCharsKeys.setCapacity(entry.count + NUM_DERIVED_KEYS_HAL3_3);
@@ -87,9 +110,12 @@
             availableCharsKeys.push(entry.data.i32[i]);
         }
         availableCharsKeys.push(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
-        availableCharsKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE);
+        availableCharsKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE);
         availableCharsKeys.push(ANDROID_CONTROL_AVAILABLE_MODES);
+        availableCharsKeys.push(ANDROID_SHADING_AVAILABLE_MODES);
+        availableCharsKeys.push(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES);
         chars.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, availableCharsKeys);
+
     }
     return;
 }
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 445c9c2..0bc8ed1 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2765,11 +2765,13 @@
             // error
             ALOGE("RequestThread: Can't get input buffer, skipping request:"
                     " %s (%d)", strerror(-res), res);
-            Mutex::Autolock l(mRequestLock);
-            if (mListener != NULL) {
-                mListener->notifyError(
-                        ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
-                        nextRequest->mResultExtras);
+            {
+                Mutex::Autolock l(mRequestLock);
+                if (mListener != NULL) {
+                    mListener->notifyError(
+                            ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
+                            nextRequest->mResultExtras);
+                }
             }
             cleanUpFailedRequest(request, nextRequest, outputBuffers);
             return true;
@@ -2792,11 +2794,13 @@
             // error
             ALOGE("RequestThread: Can't get output buffer, skipping request:"
                     " %s (%d)", strerror(-res), res);
-            Mutex::Autolock l(mRequestLock);
-            if (mListener != NULL) {
-                mListener->notifyError(
-                        ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
-                        nextRequest->mResultExtras);
+            {
+                Mutex::Autolock l(mRequestLock);
+                if (mListener != NULL) {
+                    mListener->notifyError(
+                            ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
+                            nextRequest->mResultExtras);
+                }
             }
             cleanUpFailedRequest(request, nextRequest, outputBuffers);
             return true;
@@ -2865,6 +2869,12 @@
         nextRequest->mSettings.unlock(request.settings);
     }
 
+    // Unset as current request
+    {
+        Mutex::Autolock l(mRequestLock);
+        mNextRequest.clear();
+    }
+
     // Remove any previously queued triggers (after unlock)
     res = removeTriggers(mPrevRequest);
     if (res != OK) {
@@ -2890,6 +2900,13 @@
         sp<Camera3StreamInterface>& stream) {
     Mutex::Autolock l(mRequestLock);
 
+    if (mNextRequest != nullptr) {
+        for (const auto& s : mNextRequest->mOutputStreams) {
+            if (stream == s) return true;
+        }
+        if (stream == mNextRequest->mInputStream) return true;
+    }
+
     for (const auto& request : mRequestQueue) {
         for (const auto& s : request->mOutputStreams) {
             if (stream == s) return true;
@@ -2924,6 +2941,9 @@
         nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
             outputBuffers[i], 0);
     }
+
+    Mutex::Autolock l(mRequestLock);
+    mNextRequest.clear();
 }
 
 sp<Camera3Device::CaptureRequest>
@@ -3007,6 +3027,8 @@
         nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
         nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
     }
+    mNextRequest = nextRequest;
+
     return nextRequest;
 }
 
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 4fbcb2e..fcb5180 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -501,6 +501,10 @@
         Condition          mRequestSignal;
         RequestList        mRequestQueue;
         RequestList        mRepeatingRequests;
+        // The next request being prepped for submission to the HAL, no longer
+        // on the request queue. Read-only even with mRequestLock held, outside
+        // of threadLoop
+        sp<const CaptureRequest> mNextRequest;
 
         bool               mReconfigured;