resolve merge conflicts of 3fce3ef to nyc-mr1-dev-plus-aosp

Change-Id: If319afe3976bedd64226e128164457f461eb7042
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index 1e8744b..96ecfa0 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -121,4 +121,6 @@
     void tearDown(int streamId);
 
     void prepare2(int maxCount, int streamId);
+
+    void setDeferredConfiguration(int streamId, in OutputConfiguration outputConfiguration);
 }
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index 3247d0d..38e1c01 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -42,9 +42,24 @@
     return mSurfaceSetID;
 }
 
+int OutputConfiguration::getSurfaceType() const {
+    return mSurfaceType;
+}
+
+int OutputConfiguration::getWidth() const {
+    return mWidth;
+}
+
+int OutputConfiguration::getHeight() const {
+    return mHeight;
+}
+
 OutputConfiguration::OutputConfiguration() :
         mRotation(INVALID_ROTATION),
-        mSurfaceSetID(INVALID_SET_ID) {
+        mSurfaceSetID(INVALID_SET_ID),
+        mSurfaceType(SURFACE_TYPE_UNKNOWN),
+        mWidth(0),
+        mHeight(0) {
 }
 
 OutputConfiguration::OutputConfiguration(const Parcel& parcel) :
@@ -70,18 +85,48 @@
         return err;
     }
 
+    int surfaceType = SURFACE_TYPE_UNKNOWN;
+    if ((err = parcel->readInt32(&surfaceType)) != OK) {
+        ALOGE("%s: Failed to read surface type from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int width = 0;
+    if ((err = parcel->readInt32(&width)) != OK) {
+        ALOGE("%s: Failed to read surface width from parcel", __FUNCTION__);
+        return err;
+    }
+
+    int height = 0;
+    if ((err = parcel->readInt32(&height)) != OK) {
+        ALOGE("%s: Failed to read surface height from parcel", __FUNCTION__);
+        return err;
+    }
+
     view::Surface surfaceShim;
     if ((err = surfaceShim.readFromParcel(parcel)) != OK) {
-        ALOGE("%s: Failed to read surface from parcel", __FUNCTION__);
-        return err;
+        // Read surface failure for deferred surface configuration is expected.
+        if (surfaceType == SURFACE_TYPE_SURFACE_VIEW ||
+                surfaceType == SURFACE_TYPE_SURFACE_TEXTURE) {
+            ALOGV("%s: Get null surface from a deferred surface configuration (%dx%d)",
+                    __FUNCTION__, width, height);
+            err = OK;
+        } else {
+            ALOGE("%s: Failed to read surface from parcel", __FUNCTION__);
+            return err;
+        }
     }
 
     mGbp = surfaceShim.graphicBufferProducer;
     mRotation = rotation;
     mSurfaceSetID = setID;
+    mSurfaceType = surfaceType;
+    mWidth = width;
+    mHeight = height;
 
-    ALOGV("%s: OutputConfiguration: bp = %p, name = %s, rotation = %d, setId = %d", __FUNCTION__,
-            mGbp.get(), String8(surfaceShim.name).string(), mRotation, mSurfaceSetID);
+    ALOGV("%s: OutputConfiguration: bp = %p, name = %s, rotation = %d, setId = %d,"
+            "surfaceType = %d", __FUNCTION__, mGbp.get(), String8(surfaceShim.name).string(),
+            mRotation, mSurfaceSetID, mSurfaceType);
 
     return err;
 }
@@ -104,6 +149,15 @@
     err = parcel->writeInt32(mSurfaceSetID);
     if (err != OK) return err;
 
+    err = parcel->writeInt32(mSurfaceType);
+    if (err != OK) return err;
+
+    err = parcel->writeInt32(mWidth);
+    if (err != OK) return err;
+
+    err = parcel->writeInt32(mHeight);
+    if (err != OK) return err;
+
     view::Surface surfaceShim;
     surfaceShim.name = String16("unknown_name"); // name of surface
     surfaceShim.graphicBufferProducer = mGbp;
diff --git a/camera/cameraserver/cameraserver.rc b/camera/cameraserver/cameraserver.rc
index 16d9da8..09f9789 100644
--- a/camera/cameraserver/cameraserver.rc
+++ b/camera/cameraserver/cameraserver.rc
@@ -1,6 +1,6 @@
 service cameraserver /system/bin/cameraserver
     class main
     user cameraserver
-    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
+    group audio camera input drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks
diff --git a/include/camera/camera2/OutputConfiguration.h b/include/camera/camera2/OutputConfiguration.h
index 72a3753..cf8f3c6 100644
--- a/include/camera/camera2/OutputConfiguration.h
+++ b/include/camera/camera2/OutputConfiguration.h
@@ -33,10 +33,17 @@
 
     static const int INVALID_ROTATION;
     static const int INVALID_SET_ID;
+    enum SurfaceType{
+        SURFACE_TYPE_UNKNOWN = -1,
+        SURFACE_TYPE_SURFACE_VIEW = 0,
+        SURFACE_TYPE_SURFACE_TEXTURE = 1
+    };
     sp<IGraphicBufferProducer> getGraphicBufferProducer() const;
     int                        getRotation() const;
     int                        getSurfaceSetID() const;
-
+    int                        getSurfaceType() const;
+    int                        getWidth() const;
+    int                        getHeight() const;
     /**
      * Keep impl up-to-date with OutputConfiguration.java in frameworks/base
      */
@@ -60,7 +67,10 @@
     bool operator == (const OutputConfiguration& other) const {
         return (mGbp == other.mGbp &&
                 mRotation == other.mRotation &&
-                mSurfaceSetID == other.mSurfaceSetID);
+                mSurfaceSetID == other.mSurfaceSetID &&
+                mSurfaceType == other.mSurfaceType &&
+                mWidth == other.mWidth &&
+                mHeight == other.mHeight);
     }
     bool operator != (const OutputConfiguration& other) const {
         return !(*this == other);
@@ -71,6 +81,16 @@
         if (mSurfaceSetID != other.mSurfaceSetID) {
             return mSurfaceSetID < other.mSurfaceSetID;
         }
+        if (mSurfaceType != other.mSurfaceType) {
+            return mSurfaceType < other.mSurfaceType;
+        }
+        if (mWidth != other.mWidth) {
+            return mWidth < other.mWidth;
+        }
+        if (mHeight != other.mHeight) {
+            return mHeight < other.mHeight;
+        }
+
         return mRotation < other.mRotation;
     }
     bool operator > (const OutputConfiguration& other) const {
@@ -81,6 +101,9 @@
     sp<IGraphicBufferProducer> mGbp;
     int                        mRotation;
     int                        mSurfaceSetID;
+    int                        mSurfaceType;
+    int                        mWidth;
+    int                        mHeight;
     // helper function
     static String16 readMaybeEmptyString16(const Parcel* parcel);
 };
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 2fa1a4e..63076e9 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -491,6 +491,9 @@
      */
             uint32_t    getInputFramesLost() const;
 
+    /* Get the flags */
+            audio_input_flags_t getFlags() const { AutoMutex _l(mLock); return mFlags; }
+
 private:
     /* copying audio record objects is not allowed */
                         AudioRecord(const AudioRecord& other);
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 984bc02..096f7ef 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -44,16 +44,6 @@
 public:
     DECLARE_META_INTERFACE(AudioFlinger);
 
-    // or-able bits shared by createTrack and openRecord, but not all combinations make sense
-    enum {
-        TRACK_DEFAULT = 0,  // client requests a default AudioTrack
-        // FIXME: obsolete
-        // TRACK_TIMED= 1,  // client requests a TimedAudioTrack
-        TRACK_FAST    = 2,  // client requests a fast AudioTrack or AudioRecord
-        TRACK_OFFLOAD = 4,  // client requests offload to hw codec
-        TRACK_DIRECT = 8,   // client requests a direct output
-    };
-    typedef uint32_t track_flags_t;
 
     // invariant on exit for all APIs that return an sp<>:
     //   (return value != 0) == (*status == NO_ERROR)
@@ -67,7 +57,7 @@
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
                                 size_t *pFrameCount,
-                                track_flags_t *flags,
+                                audio_output_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 // On successful return, AudioFlinger takes over the handle
                                 // reference and will release it when the track is destroyed.
@@ -89,7 +79,7 @@
                                 audio_channel_mask_t channelMask,
                                 const String16& callingPackage,
                                 size_t *pFrameCount,
-                                track_flags_t *flags,
+                                audio_input_flags_t *flags,
                                 pid_t pid,
                                 pid_t tid,  // -1 means unused, otherwise must be valid non-0
                                 int clientUid,
diff --git a/include/media/IMediaSource.h b/include/media/IMediaSource.h
index 709f425..524e7aa 100644
--- a/include/media/IMediaSource.h
+++ b/include/media/IMediaSource.h
@@ -114,6 +114,9 @@
     virtual status_t readMultiple(
             Vector<MediaBuffer *> *buffers, uint32_t maxNumBuffers = 1) = 0;
 
+    // Returns true if |readMultiple| is supported, otherwise false.
+    virtual bool supportReadMultiple() = 0;
+
     // Causes this source to suspend pulling data from its upstream source
     // until a subsequent read-with-seek. Currently only supported by
     // OMXCodec.
@@ -148,6 +151,10 @@
             Vector<MediaBuffer *> * /* buffers */, uint32_t /* maxNumBuffers = 1 */) {
         return ERROR_UNSUPPORTED;
     }
+
+    virtual bool supportReadMultiple() {
+        return false;
+    }
 protected:
     virtual ~BnMediaSource();
 
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index d9bb856..9a87023 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -593,11 +593,10 @@
     size_t notificationFrames = mNotificationFramesReq;
     size_t frameCount = mReqFrameCount;
 
-    IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT;
+    audio_input_flags_t flags = mFlags;
 
     pid_t tid = -1;
     if (mFlags & AUDIO_INPUT_FLAG_FAST) {
-        trackFlags |= IAudioFlinger::TRACK_FAST;
         if (mAudioRecordThread != 0) {
             tid = mAudioRecordThread->getTid();
         }
@@ -615,7 +614,7 @@
                                                        mChannelMask,
                                                        opPackageName,
                                                        &temp,
-                                                       &trackFlags,
+                                                       &flags,
                                                        mClientPid,
                                                        tid,
                                                        mClientUid,
@@ -638,7 +637,7 @@
 
     mAwaitBoost = false;
     if (mFlags & AUDIO_INPUT_FLAG_FAST) {
-        if (trackFlags & IAudioFlinger::TRACK_FAST) {
+        if (flags & AUDIO_INPUT_FLAG_FAST) {
             ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu", frameCount);
             mAwaitBoost = true;
         } else {
@@ -648,6 +647,7 @@
             continue;   // retry
         }
     }
+    mFlags = flags;
 
     if (iMem == 0) {
         ALOGE("Could not get control block");
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index e8c3466..ed7b856 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1372,24 +1372,15 @@
         }
     }
 
-    IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT;
+    audio_output_flags_t flags = mFlags;
 
     pid_t tid = -1;
     if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
-        trackFlags |= IAudioFlinger::TRACK_FAST;
         if (mAudioTrackThread != 0 && !mThreadCanCallJava) {
             tid = mAudioTrackThread->getTid();
         }
     }
 
-    if (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
-        trackFlags |= IAudioFlinger::TRACK_OFFLOAD;
-    }
-
-    if (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
-        trackFlags |= IAudioFlinger::TRACK_DIRECT;
-    }
-
     size_t temp = frameCount;   // temp may be replaced by a revised value of frameCount,
                                 // but we will still need the original value also
     audio_session_t originalSessionId = mSessionId;
@@ -1398,7 +1389,7 @@
                                                       mFormat,
                                                       mChannelMask,
                                                       &temp,
-                                                      &trackFlags,
+                                                      &flags,
                                                       mSharedBuffer,
                                                       output,
                                                       mClientPid,
@@ -1451,23 +1442,23 @@
 
     mAwaitBoost = false;
     if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
-        if (trackFlags & IAudioFlinger::TRACK_FAST) {
+        if (flags & AUDIO_OUTPUT_FLAG_FAST) {
             ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %zu", frameCount);
             if (!mThreadCanCallJava) {
                 mAwaitBoost = true;
             }
         } else {
             ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %zu", frameCount);
-            mFlags = (audio_output_flags_t) (mFlags & ~AUDIO_OUTPUT_FLAG_FAST);
         }
     }
+    mFlags = flags;
 
     // Make sure that application is notified with sufficient margin before underrun.
     // The client can divide the AudioTrack buffer into sub-buffers,
     // and expresses its desire to server as the notification frame count.
     if (mSharedBuffer == 0 && audio_is_linear_pcm(mFormat)) {
         size_t maxNotificationFrames;
-        if (trackFlags & IAudioFlinger::TRACK_FAST) {
+        if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
             // notify every HAL buffer, regardless of the size of the track buffer
             maxNotificationFrames = afFrameCountHAL;
         } else {
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 4fc3c9f..65fdedb 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -101,7 +101,7 @@
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
                                 size_t *pFrameCount,
-                                track_flags_t *flags,
+                                audio_output_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
                                 pid_t pid,
@@ -119,7 +119,7 @@
         data.writeInt32(channelMask);
         size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
         data.writeInt64(frameCount);
-        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
+        audio_output_flags_t lFlags = flags != NULL ? *flags : AUDIO_OUTPUT_FLAG_NONE;
         data.writeInt32(lFlags);
         // haveSharedBuffer
         if (sharedBuffer != 0) {
@@ -145,7 +145,7 @@
             if (pFrameCount != NULL) {
                 *pFrameCount = frameCount;
             }
-            lFlags = reply.readInt32();
+            lFlags = (audio_output_flags_t)reply.readInt32();
             if (flags != NULL) {
                 *flags = lFlags;
             }
@@ -180,7 +180,7 @@
                                 audio_channel_mask_t channelMask,
                                 const String16& opPackageName,
                                 size_t *pFrameCount,
-                                track_flags_t *flags,
+                                audio_input_flags_t *flags,
                                 pid_t pid,
                                 pid_t tid,
                                 int clientUid,
@@ -200,7 +200,7 @@
         data.writeString16(opPackageName);
         size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
         data.writeInt64(frameCount);
-        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
+        audio_input_flags_t lFlags = flags != NULL ? *flags : AUDIO_INPUT_FLAG_NONE;
         data.writeInt32(lFlags);
         data.writeInt32((int32_t) pid);
         data.writeInt32((int32_t) tid);
@@ -221,7 +221,7 @@
             if (pFrameCount != NULL) {
                 *pFrameCount = frameCount;
             }
-            lFlags = reply.readInt32();
+            lFlags = (audio_input_flags_t)reply.readInt32();
             if (flags != NULL) {
                 *flags = lFlags;
             }
@@ -947,7 +947,7 @@
             audio_format_t format = (audio_format_t) data.readInt32();
             audio_channel_mask_t channelMask = data.readInt32();
             size_t frameCount = data.readInt64();
-            track_flags_t flags = (track_flags_t) data.readInt32();
+            audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
             bool haveSharedBuffer = data.readInt32() != 0;
             sp<IMemory> buffer;
             if (haveSharedBuffer) {
@@ -986,7 +986,7 @@
             audio_channel_mask_t channelMask = data.readInt32();
             const String16& opPackageName = data.readString16();
             size_t frameCount = data.readInt64();
-            track_flags_t flags = (track_flags_t) data.readInt32();
+            audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
             pid_t pid = (pid_t) data.readInt32();
             pid_t tid = (pid_t) data.readInt32();
             int clientUid = data.readInt32();
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index 7e40e4f..d2b4291 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -221,6 +221,10 @@
         return ret;
     }
 
+    bool supportReadMultiple() {
+        return true;
+    }
+
     virtual status_t pause() {
         ALOGV("pause");
         Parcel data, reply;
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 8725dfe..fbe749c 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -395,7 +395,9 @@
         return BAD_VALUE;
     }
     Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) return INVALID_OPERATION;
+    if (mPlayer == 0 || (mCurrentState & MEDIA_PLAYER_STOPPED)) {
+        return INVALID_OPERATION;
+    }
 
     if (rate.mSpeed != 0.f && !(mCurrentState & MEDIA_PLAYER_STARTED)
             && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 56042d4..3d836c8 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1420,7 +1420,9 @@
         options.setNonBlocking();
     }
 
-    bool couldReadMultiple = (!mIsWidevine && trackType == MEDIA_TRACK_TYPE_AUDIO);
+    bool couldReadMultiple =
+        (!mIsWidevine && trackType == MEDIA_TRACK_TYPE_AUDIO
+                && track->mSource->supportReadMultiple());
     for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
         Vector<MediaBuffer *> mediaBuffers;
         status_t err = NO_ERROR;
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index d7cf1e9..ff59fb1 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -648,6 +648,15 @@
             CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
             timeUs += mInputBufferTimeOffsetUs;
 
+            // Due to the extra delay adjustment at the beginning of start/resume,
+            // the adjusted timeUs may be negative if MediaCodecSource goes into pause
+            // state before feeding any buffers to the encoder. Drop the buffer in this
+            // case.
+            if (timeUs < 0) {
+                mbuf->release();
+                return OK;
+            }
+
             // push decoding time for video, or drift time for audio
             if (mIsVideo) {
                 mDecodingTimeQueue.push_back(timeUs);
@@ -832,9 +841,16 @@
                         // Time offset is not applied at
                         // feedEncoderInputBuffer() in surface input case.
                         timeUs += mInputBufferTimeOffsetUs;
-                        // GraphicBufferSource is supposed to discard samples
-                        // queued before start, and offset timeUs by start time
-                        CHECK_GE(timeUs, 0ll);
+
+                        // Due to the extra delay adjustment at the beginning of
+                        // start/resume, the adjusted timeUs may be negative if
+                        // MediaCodecSource goes into pause state before feeding
+                        // any buffers to the encoder. Drop the buffer in this case.
+                        if (timeUs < 0) {
+                            mEncoder->releaseOutputBuffer(index);
+                            break;
+                        }
+
                         // TODO:
                         // Decoding time for surface source is unavailable,
                         // use presentation time for now. May need to move
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index c429a7f..a757aac 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -576,7 +576,7 @@
         audio_format_t format,
         audio_channel_mask_t channelMask,
         size_t *frameCount,
-        IAudioFlinger::track_flags_t *flags,
+        audio_output_flags_t *flags,
         const sp<IMemory>& sharedBuffer,
         audio_io_handle_t output,
         pid_t pid,
@@ -1467,7 +1467,7 @@
         audio_channel_mask_t channelMask,
         const String16& opPackageName,
         size_t *frameCount,
-        IAudioFlinger::track_flags_t *flags,
+        audio_input_flags_t *flags,
         pid_t pid,
         pid_t tid,
         int clientUid,
@@ -2199,7 +2199,7 @@
         }
 #endif
 
-        AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream);
+        AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream, flags);
 
         // Start record thread
         // RecordThread requires both input and output device indication to forward to audio
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 59ad688..4a5a643 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -104,7 +104,7 @@
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
                                 size_t *pFrameCount,
-                                IAudioFlinger::track_flags_t *flags,
+                                audio_output_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
                                 pid_t pid,
@@ -120,7 +120,7 @@
                                 audio_channel_mask_t channelMask,
                                 const String16& opPackageName,
                                 size_t *pFrameCount,
-                                IAudioFlinger::track_flags_t *flags,
+                                audio_input_flags_t *flags,
                                 pid_t pid,
                                 pid_t tid,
                                 int clientUid,
@@ -609,11 +609,12 @@
     struct AudioStreamIn {
         AudioHwDevice* const audioHwDev;
         audio_stream_in_t* const stream;
+        audio_input_flags_t flags;
 
         audio_hw_device_t* hwDev() const { return audioHwDev->hwDevice(); }
 
-        AudioStreamIn(AudioHwDevice *dev, audio_stream_in_t *in) :
-            audioHwDev(dev), stream(in) {}
+        AudioStreamIn(AudioHwDevice *dev, audio_stream_in_t *in, audio_input_flags_t flags) :
+            audioHwDev(dev), stream(in), flags(flags) {}
     };
 
     // for mAudioSessionRefs only
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index f8671b5..bee17fd 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -168,12 +168,46 @@
                 ALOGV("createAudioPatch() removing patch handle %d", *handle);
                 halHandle = mPatches[index]->mHalHandle;
                 Patch *removedPatch = mPatches[index];
+                // free resources owned by the removed patch if applicable
+                // 1) if a software patch is present, release the playback and capture threads and
+                // tracks created. This will also release the corresponding audio HAL patches
                 if ((removedPatch->mRecordPatchHandle
                         != AUDIO_PATCH_HANDLE_NONE) ||
                         (removedPatch->mPlaybackPatchHandle !=
                                 AUDIO_PATCH_HANDLE_NONE)) {
                     clearPatchConnections(removedPatch);
                 }
+                // 2) if the new patch and old patch source or sink are devices from different
+                // hw modules,  clear the audio HAL patches now because they will not be updated
+                // by call to create_audio_patch() below which will happen on a different HW module
+                if (halHandle != AUDIO_PATCH_HANDLE_NONE) {
+                    audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
+                    if ((removedPatch->mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE) &&
+                        ((patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE) ||
+                          (removedPatch->mAudioPatch.sources[0].ext.device.hw_module !=
+                           patch->sources[0].ext.device.hw_module))) {
+                        hwModule = removedPatch->mAudioPatch.sources[0].ext.device.hw_module;
+                    } else if ((patch->num_sinks == 0) ||
+                            ((removedPatch->mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
+                             ((patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) ||
+                              (removedPatch->mAudioPatch.sinks[0].ext.device.hw_module !=
+                               patch->sinks[0].ext.device.hw_module)))) {
+                        // Note on (patch->num_sinks == 0): this situation should not happen as
+                        // these special patches are only created by the policy manager but just
+                        // in case, systematically clear the HAL patch.
+                        // Note that removedPatch->mAudioPatch.num_sinks cannot be 0 here because
+                        // halHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
+                        hwModule = removedPatch->mAudioPatch.sinks[0].ext.device.hw_module;
+                    }
+                    if (hwModule != AUDIO_MODULE_HANDLE_NONE) {
+                        ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(hwModule);
+                        if (index >= 0) {
+                            audio_hw_device_t *hwDevice =
+                                    audioflinger->mAudioHwDevs.valueAt(index)->hwDevice();
+                            hwDevice->release_audio_patch(hwDevice, halHandle);
+                        }
+                    }
+                }
                 mPatches.removeAt(index);
                 delete removedPatch;
                 break;
@@ -437,7 +471,7 @@
                                              format,
                                              frameCount,
                                              NULL,
-                                             IAudioFlinger::TRACK_DEFAULT);
+                                             AUDIO_INPUT_FLAG_NONE);
     if (patch->mPatchRecord == 0) {
         return NO_MEMORY;
     }
@@ -457,7 +491,7 @@
                                            format,
                                            frameCount,
                                            patch->mPatchRecord->buffer(),
-                                           IAudioFlinger::TRACK_DEFAULT);
+                                           AUDIO_OUTPUT_FLAG_NONE);
     if (patch->mPatchTrack == 0) {
         return NO_MEMORY;
     }
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index e31179c..16ec278 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -62,12 +62,24 @@
 
         struct audio_patch              mAudioPatch;
         audio_patch_handle_t            mHandle;
+        // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
         audio_patch_handle_t            mHalHandle;
+        // below members are used by a software audio patch connecting a source device from a
+        // given audio HW module to a sink device on an other audio HW module.
+        // playback thread created by createAudioPatch() and released by clearPatchConnections() if
+        // no existing playback thread can be used by the software patch
         sp<PlaybackThread>              mPlaybackThread;
+        // audio track created by createPatchConnections() and released by clearPatchConnections()
         sp<PlaybackThread::PatchTrack>  mPatchTrack;
+        // record thread created by createAudioPatch() and released by clearPatchConnections()
         sp<RecordThread>                mRecordThread;
+        // audio record created by createPatchConnections() and released by clearPatchConnections()
         sp<RecordThread::PatchRecord>   mPatchRecord;
+        // handle for audio patch connecting source device to record thread input.
+        // created by createPatchConnections() and released by clearPatchConnections()
         audio_patch_handle_t            mRecordPatchHandle;
+        // handle for audio patch connecting playback thread output to sink device
+        // created by createPatchConnections() and released by clearPatchConnections()
         audio_patch_handle_t            mPlaybackPatchHandle;
 
     };
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 270e27f..5601bde 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -33,7 +33,7 @@
                                 const sp<IMemory>& sharedBuffer,
                                 audio_session_t sessionId,
                                 int uid,
-                                IAudioFlinger::track_flags_t flags,
+                                audio_output_flags_t flags,
                                 track_type type);
     virtual             ~Track();
     virtual status_t    initCheck() const;
@@ -55,8 +55,9 @@
             audio_stream_type_t streamType() const {
                 return mStreamType;
             }
-            bool        isOffloaded() const { return (mFlags & IAudioFlinger::TRACK_OFFLOAD) != 0; }
-            bool        isDirect() const { return (mFlags & IAudioFlinger::TRACK_DIRECT) != 0; }
+            bool        isOffloaded() const
+                                { return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; }
+            bool        isDirect() const { return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; }
             status_t    setParameters(const String8& keyValuePairs);
             status_t    attachAuxEffect(int EffectId);
             void        setAuxBuffer(int EffectId, int32_t *buffer);
@@ -72,6 +73,8 @@
 
     virtual status_t    setSyncEvent(const sp<SyncEvent>& event);
 
+    virtual bool        isFastTrack() const { return (mFlags & AUDIO_OUTPUT_FLAG_FAST) != 0; }
+
 protected:
     // for numerous
     friend class PlaybackThread;
@@ -166,7 +169,7 @@
     AudioTrackServerProxy*  mAudioTrackServerProxy;
     bool                mResumeToStopping; // track was paused in stopping state.
     bool                mFlushHwPending; // track requests for thread flush
-
+    audio_output_flags_t mFlags;
 };  // end of Track
 
 
@@ -226,7 +229,7 @@
                                    audio_format_t format,
                                    size_t frameCount,
                                    void *buffer,
-                                   IAudioFlinger::track_flags_t flags);
+                                   audio_output_flags_t flags);
     virtual             ~PatchTrack();
 
     virtual status_t    start(AudioSystem::sync_event_t event =
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 13396a6..123e033 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -31,7 +31,7 @@
                                 void *buffer,
                                 audio_session_t sessionId,
                                 int uid,
-                                IAudioFlinger::track_flags_t flags,
+                                audio_input_flags_t flags,
                                 track_type type);
     virtual             ~RecordTrack();
     virtual status_t    initCheck() const;
@@ -58,6 +58,9 @@
                                              int64_t sourceFramesRead,
                                              uint32_t halSampleRate,
                                              const ExtendedTimestamp &timestamp);
+
+    virtual bool        isFastTrack() const { return (mFlags & AUDIO_INPUT_FLAG_FAST) != 0; }
+
 private:
     friend class AudioFlinger;  // for mState
 
@@ -86,6 +89,7 @@
 
             // used by the record thread to convert frames to proper destination format
             RecordBufferConverter              *mRecordBufferConverter;
+            audio_input_flags_t                mFlags;
 };
 
 // playback track, used by PatchPanel
@@ -98,7 +102,7 @@
                 audio_format_t format,
                 size_t frameCount,
                 void *buffer,
-                IAudioFlinger::track_flags_t flags);
+                audio_input_flags_t flags);
     virtual             ~PatchRecord();
 
     // AudioBufferProvider interface
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index cab5517..20b259a 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1753,7 +1753,7 @@
         size_t *pFrameCount,
         const sp<IMemory>& sharedBuffer,
         audio_session_t sessionId,
-        IAudioFlinger::track_flags_t *flags,
+        audio_output_flags_t *flags,
         pid_t tid,
         int uid,
         status_t *status)
@@ -1761,9 +1761,22 @@
     size_t frameCount = *pFrameCount;
     sp<Track> track;
     status_t lStatus;
+    audio_output_flags_t outputFlags = mOutput->flags;
+
+    // special case for FAST flag considered OK if fast mixer is present
+    if (hasFastMixer()) {
+        outputFlags = (audio_output_flags_t)(outputFlags | AUDIO_OUTPUT_FLAG_FAST);
+    }
+
+    // Check if requested flags are compatible with output stream flags
+    if ((*flags & outputFlags) != *flags) {
+        ALOGW("createTrack_l(): mismatch between requested flags (%08x) and output flags (%08x)",
+              *flags, outputFlags);
+        *flags = (audio_output_flags_t)(*flags & outputFlags);
+    }
 
     // client expresses a preference for FAST, but we get the final say
-    if (*flags & IAudioFlinger::TRACK_FAST) {
+    if (*flags & AUDIO_OUTPUT_FLAG_FAST) {
       if (
             // PCM data
             audio_is_linear_pcm(format) &&
@@ -1801,7 +1814,7 @@
                 sharedBuffer.get(), frameCount, mFrameCount, format, mFormat,
                 audio_is_linear_pcm(format),
                 channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask);
-        *flags &= ~IAudioFlinger::TRACK_FAST;
+        *flags = (audio_output_flags_t)(*flags &~AUDIO_OUTPUT_FLAG_FAST);
       }
     }
     // For normal PCM streaming tracks, update minimum frame count.
@@ -1809,7 +1822,7 @@
     // to be at least 2 x the normal mixer frame count and cover audio hardware latency.
     // This is probably too conservative, but legacy application code may depend on it.
     // If you change this calculation, also review the start threshold which is related.
-    if (!(*flags & IAudioFlinger::TRACK_FAST)
+    if (!(*flags & AUDIO_OUTPUT_FLAG_FAST)
             && audio_has_proportional_frames(format) && sharedBuffer == 0) {
         // this must match AudioTrack.cpp calculateMinFrameCount().
         // TODO: Move to a common library
@@ -1917,7 +1930,7 @@
             chain->incTrackCnt();
         }
 
-        if ((*flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
+        if ((*flags & AUDIO_OUTPUT_FLAG_FAST) && (tid != -1)) {
             pid_t callingPid = IPCThreadState::self()->getCallingPid();
             // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
             // so ask activity manager to do this on our behalf
@@ -2285,6 +2298,7 @@
             kUseFastMixer == FastMixer_Dynamic)) {
         size_t minNormalFrameCount = (kMinNormalSinkBufferSizeMs * mSampleRate) / 1000;
         size_t maxNormalFrameCount = (kMaxNormalSinkBufferSizeMs * mSampleRate) / 1000;
+
         // round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer
         minNormalFrameCount = (minNormalFrameCount + 15) & ~15;
         maxNormalFrameCount = maxNormalFrameCount & ~15;
@@ -2301,18 +2315,7 @@
                 multiplier = (double) maxNormalFrameCount / (double) mFrameCount;
             }
         } else {
-            // prefer an even multiplier, for compatibility with doubling of fast tracks due to HAL
-            // SRC (it would be unusual for the normal sink buffer size to not be a multiple of fast
-            // track, but we sometimes have to do this to satisfy the maximum frame count
-            // constraint)
-            // FIXME this rounding up should not be done if no HAL SRC
-            uint32_t truncMult = (uint32_t) multiplier;
-            if ((truncMult & 1)) {
-                if ((truncMult + 1) * mFrameCount <= maxNormalFrameCount) {
-                    ++truncMult;
-                }
-            }
-            multiplier = (double) truncMult;
+            multiplier = floor(multiplier);
         }
     }
     mNormalFrameCount = multiplier * mFrameCount;
@@ -3175,6 +3178,11 @@
                         // (1) mixer threads without a fast mixer (which has its own warm-up)
                         // (2) minimum buffer sized tracks (even if the track is full,
                         //     the app won't fill fast enough to handle the sudden draw).
+                        //
+                        // Total time spent in last processing cycle equals time spent in
+                        // 1. threadLoop_write, as well as time spent in
+                        // 2. threadLoop_mix (significant for heavy mixing, especially
+                        //                    on low tier processors)
 
                         // it's OK if deltaMs is an overestimate.
                         const int32_t deltaMs =
@@ -6282,16 +6290,30 @@
         audio_session_t sessionId,
         size_t *notificationFrames,
         int uid,
-        IAudioFlinger::track_flags_t *flags,
+        audio_input_flags_t *flags,
         pid_t tid,
         status_t *status)
 {
     size_t frameCount = *pFrameCount;
     sp<RecordTrack> track;
     status_t lStatus;
+    audio_input_flags_t inputFlags = mInput->flags;
+
+    // special case for FAST flag considered OK if fast capture is present
+    if (hasFastCapture()) {
+        inputFlags = (audio_input_flags_t)(inputFlags | AUDIO_INPUT_FLAG_FAST);
+    }
+
+    // Check if requested flags are compatible with output stream flags
+    if ((*flags & inputFlags) != *flags) {
+        ALOGW("createRecordTrack_l(): mismatch between requested flags (%08x) and"
+                " input flags (%08x)",
+              *flags, inputFlags);
+        *flags = (audio_input_flags_t)(*flags & inputFlags);
+    }
 
     // client expresses a preference for FAST, but we get the final say
-    if (*flags & IAudioFlinger::TRACK_FAST) {
+    if (*flags & AUDIO_INPUT_FLAG_FAST) {
       if (
             // we formerly checked for a callback handler (non-0 tid),
             // but that is no longer required for TRANSFER_OBTAIN mode
@@ -6320,12 +6342,12 @@
                 frameCount, mFrameCount, mPipeFramesP2,
                 format, audio_is_linear_pcm(format), channelMask, sampleRate, mSampleRate,
                 hasFastCapture(), tid, mFastTrackAvail);
-        *flags &= ~IAudioFlinger::TRACK_FAST;
+        *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST);
       }
     }
 
     // compute track buffer size in frames, and suggest the notification frame count
-    if (*flags & IAudioFlinger::TRACK_FAST) {
+    if (*flags & AUDIO_INPUT_FLAG_FAST) {
         // fast track: frame count is exactly the pipe depth
         frameCount = mPipeFramesP2;
         // ignore requested notificationFrames, and always notify exactly once every HAL buffer
@@ -6381,7 +6403,7 @@
         setEffectSuspended_l(FX_IID_AEC, suspend, sessionId);
         setEffectSuspended_l(FX_IID_NS, suspend, sessionId);
 
-        if ((*flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
+        if ((*flags & AUDIO_INPUT_FLAG_FAST) && (tid != -1)) {
             pid_t callingPid = IPCThreadState::self()->getCallingPid();
             // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
             // so ask activity manager to do this on our behalf
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 787b5c4..0b4fbb9 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -566,7 +566,7 @@
                                 size_t *pFrameCount,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_session_t sessionId,
-                                IAudioFlinger::track_flags_t *flags,
+                                audio_output_flags_t *flags,
                                 pid_t tid,
                                 int uid,
                                 status_t *status /*non-NULL*/);
@@ -1258,7 +1258,7 @@
                     audio_session_t sessionId,
                     size_t *notificationFrames,
                     int uid,
-                    IAudioFlinger::track_flags_t *flags,
+                    audio_input_flags_t *flags,
                     pid_t tid,
                     status_t *status /*non-NULL*/);
 
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 67a5e58..6b97246 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -63,7 +63,6 @@
                                 void *buffer,
                                 audio_session_t sessionId,
                                 int uid,
-                                IAudioFlinger::track_flags_t flags,
                                 bool isOut,
                                 alloc_type alloc = ALLOC_CBLK,
                                 track_type type = TYPE_DEFAULT);
@@ -81,7 +80,7 @@
 
             sp<IMemory> getBuffers() const { return mBufferMemory; }
             void*       buffer() const { return mBuffer; }
-            bool        isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
+    virtual bool        isFastTrack() const = 0;
             bool        isOutputTrack() const { return (mType == TYPE_OUTPUT); }
             bool        isPatchTrack() const { return (mType == TYPE_PATCH); }
             bool        isExternalTrack() const { return !isOutputTrack() && !isPatchTrack(); }
@@ -156,7 +155,6 @@
     const audio_session_t mSessionId;
     int                 mUid;
     Vector < sp<SyncEvent> >mSyncEvents;
-    const IAudioFlinger::track_flags_t mFlags;
     const bool          mIsOut;
     ServerProxy*        mServerProxy;
     const int           mId;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 364e339..b387af3 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -73,7 +73,6 @@
             void *buffer,
             audio_session_t sessionId,
             int clientUid,
-            IAudioFlinger::track_flags_t flags,
             bool isOut,
             alloc_type alloc,
             track_type type)
@@ -93,7 +92,6 @@
                 mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
         mFrameCount(frameCount),
         mSessionId(sessionId),
-        mFlags(flags),
         mIsOut(isOut),
         mServerProxy(NULL),
         mId(android_atomic_inc(&nextTrackId)),
@@ -345,11 +343,11 @@
             const sp<IMemory>& sharedBuffer,
             audio_session_t sessionId,
             int uid,
-            IAudioFlinger::track_flags_t flags,
+            audio_output_flags_t flags,
             track_type type)
     :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
                   (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
-                  sessionId, uid, flags, true /*isOut*/,
+                  sessionId, uid, true /*isOut*/,
                   (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
                   type),
     mFillingUpStatus(FS_INVALID),
@@ -368,7 +366,8 @@
     mIsInvalid(false),
     mAudioTrackServerProxy(NULL),
     mResumeToStopping(false),
-    mFlushHwPending(false)
+    mFlushHwPending(false),
+    mFlags(flags)
 {
     // client == 0 implies sharedBuffer == 0
     ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
@@ -395,7 +394,7 @@
         return;
     }
     // only allocate a fast track index if we were able to allocate a normal track name
-    if (flags & IAudioFlinger::TRACK_FAST) {
+    if (flags & AUDIO_OUTPUT_FLAG_FAST) {
         // FIXME: Not calling framesReadyIsCalledByMultipleThreads() exposes a potential
         // race with setSyncEvent(). However, if we call it, we cannot properly start
         // static fast tracks (SoundPool) immediately after stopping.
@@ -1133,7 +1132,7 @@
             int uid)
     :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
               sampleRate, format, channelMask, frameCount,
-              NULL, 0, AUDIO_SESSION_NONE, uid, IAudioFlinger::TRACK_DEFAULT,
+              NULL, 0, AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
               TYPE_OUTPUT),
     mActive(false), mSourceThread(sourceThread), mClientProxy(NULL)
 {
@@ -1329,7 +1328,7 @@
                                                      audio_format_t format,
                                                      size_t frameCount,
                                                      void *buffer,
-                                                     IAudioFlinger::track_flags_t flags)
+                                                     audio_output_flags_t flags)
     :   Track(playbackThread, NULL, streamType,
               sampleRate, format, channelMask, frameCount,
               buffer, 0, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
@@ -1468,19 +1467,19 @@
             void *buffer,
             audio_session_t sessionId,
             int uid,
-            IAudioFlinger::track_flags_t flags,
+            audio_input_flags_t flags,
             track_type type)
     :   TrackBase(thread, client, sampleRate, format,
-                  channelMask, frameCount, buffer, sessionId, uid,
-                  flags, false /*isOut*/,
+                  channelMask, frameCount, buffer, sessionId, uid, false /*isOut*/,
                   (type == TYPE_DEFAULT) ?
-                          ((flags & IAudioFlinger::TRACK_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
+                          ((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
                           ((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
                   type),
         mOverflow(false),
         mFramesToDrop(0),
         mResamplerBufferProvider(NULL), // initialize in case of early constructor exit
-        mRecordBufferConverter(NULL)
+        mRecordBufferConverter(NULL),
+        mFlags(flags)
 {
     if (mCblk == NULL) {
         return;
@@ -1505,7 +1504,7 @@
 
     mResamplerBufferProvider = new ResamplerBufferProvider(this);
 
-    if (flags & IAudioFlinger::TRACK_FAST) {
+    if (flags & AUDIO_INPUT_FLAG_FAST) {
         ALOG_ASSERT(thread->mFastTrackAvail);
         thread->mFastTrackAvail = false;
     }
@@ -1664,7 +1663,7 @@
                                                      audio_format_t format,
                                                      size_t frameCount,
                                                      void *buffer,
-                                                     IAudioFlinger::track_flags_t flags)
+                                                     audio_input_flags_t flags)
     :   RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
                 buffer, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
                 mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 0a00368..5d64e44 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1499,6 +1499,8 @@
                                   profileFlags);
         if (profile != 0) {
             break; // success
+        } else if (profileFlags & AUDIO_INPUT_FLAG_RAW) {
+            profileFlags = (audio_input_flags_t) (profileFlags & ~AUDIO_INPUT_FLAG_RAW); // retry
         } else if (profileFlags != AUDIO_INPUT_FLAG_NONE) {
             profileFlags = AUDIO_INPUT_FLAG_NONE; // retry
         } else { // fail
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index dbec34e..a7fe5e7 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -338,13 +338,15 @@
 
     status_t err = mDevice->configureStreams(isConstrainedHighSpeed);
     if (err == BAD_VALUE) {
-        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
-                "Camera %d: Unsupported set of inputs/outputs provided",
+        String8 msg = String8::format("Camera %d: Unsupported set of inputs/outputs provided",
                 mCameraId);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
     } else if (err != OK) {
-        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
-                "Camera %d: Error configuring streams: %s (%d)",
+        String8 msg = String8::format("Camera %d: Error configuring streams: %s (%d)",
                 mCameraId, strerror(-err), err);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
     }
 
     return res;
@@ -365,6 +367,7 @@
 
     bool isInput = false;
     ssize_t index = NAME_NOT_FOUND;
+    ssize_t dIndex = NAME_NOT_FOUND;
 
     if (mInputStream.configured && mInputStream.id == streamId) {
         isInput = true;
@@ -378,10 +381,19 @@
         }
 
         if (index == NAME_NOT_FOUND) {
-            String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no such "
-                    "stream created yet", mCameraId, streamId);
-            ALOGW("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+            // See if this stream is one of the deferred streams.
+            for (size_t i = 0; i < mDeferredStreams.size(); ++i) {
+                if (streamId == mDeferredStreams[i]) {
+                    dIndex = i;
+                    break;
+                }
+            }
+            if (dIndex == NAME_NOT_FOUND) {
+                String8 msg = String8::format("Camera %d: Invalid stream ID (%d) specified, no such"
+                        " stream created yet", mCameraId, streamId);
+                ALOGW("%s: %s", __FUNCTION__, msg.string());
+                return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+            }
         }
     }
 
@@ -396,8 +408,10 @@
     } else {
         if (isInput) {
             mInputStream.configured = false;
-        } else {
+        } else if (index != NAME_NOT_FOUND) {
             mStreamMap.removeItemsAt(index);
+        } else {
+            mDeferredStreams.removeItemsAt(dIndex);
         }
     }
 
@@ -416,14 +430,30 @@
     Mutex::Autolock icl(mBinderSerializationLock);
 
     sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
-    if (bufferProducer == NULL) {
-        ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
+    bool deferredConsumer = bufferProducer == NULL;
+    int surfaceType = outputConfiguration.getSurfaceType();
+    bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
+            (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
+    if (deferredConsumer && !validSurfaceType) {
+        ALOGE("%s: Target surface is invalid: bufferProducer = %p, surfaceType = %d.",
+                __FUNCTION__, bufferProducer.get(), surfaceType);
         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
     }
+
     if (!mDevice.get()) {
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
+    int width, height, format;
+    int32_t consumerUsage;
+    android_dataspace dataSpace;
+    status_t err;
+
+    // Create stream for deferred surface case.
+    if (deferredConsumer) {
+        return createDeferredSurfaceStreamLocked(outputConfiguration, newStreamId);
+    }
+
     // Don't create multiple streams for the same target surface
     {
         ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
@@ -435,13 +465,10 @@
         }
     }
 
-    status_t err;
-
     // HACK b/10949105
     // Query consumer usage bits to set async operation mode for
     // GLConsumer using controlledByApp parameter.
     bool useAsync = false;
-    int32_t consumerUsage;
     if ((err = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
             &consumerUsage)) != OK) {
         String8 msg = String8::format("Camera %d: Failed to query Surface consumer usage: %s (%d)",
@@ -450,8 +477,8 @@
         return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
     }
     if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
-        ALOGW("%s: Camera %d: Forcing asynchronous mode for stream",
-                __FUNCTION__, mCameraId);
+        ALOGW("%s: Camera %d with consumer usage flag: 0x%x: Forcing asynchronous mode for stream",
+                __FUNCTION__, mCameraId, consumerUsage);
         useAsync = true;
     }
 
@@ -467,9 +494,6 @@
     sp<Surface> surface = new Surface(bufferProducer, useAsync);
     ANativeWindow *anw = surface.get();
 
-    int width, height, format;
-    android_dataspace dataSpace;
-
     if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
         String8 msg = String8::format("Camera %d: Failed to query Surface width: %s (%d)",
                 mCameraId, strerror(-err), err);
@@ -526,29 +550,12 @@
     } else {
         mStreamMap.add(binder, streamId);
 
-        ALOGV("%s: Camera %d: Successfully created a new stream ID %d",
-              __FUNCTION__, mCameraId, streamId);
+        ALOGV("%s: Camera %d: Successfully created a new stream ID %d for output surface"
+                " (%d x %d) with format 0x%x.",
+              __FUNCTION__, mCameraId, streamId, width, height, format);
 
-        /**
-         * Set the stream transform flags to automatically
-         * rotate the camera stream for preview use cases.
-         */
-        int32_t transform = 0;
-        err = getRotationTransformLocked(&transform);
-
-        if (err != OK) {
-            // Error logged by getRotationTransformLocked.
-            return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
-                    "Unable to calculate rotation transform for new stream");
-        }
-
-        err = mDevice->setStreamTransform(streamId, transform);
-        if (err != OK) {
-            String8 msg = String8::format("Failed to set stream transform (stream id %d)",
-                    streamId);
-            ALOGE("%s: %s", __FUNCTION__, msg.string());
-            return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
-        }
+        // Set transform flags to ensure preview to be rotated correctly.
+        res = setStreamTransformLocked(streamId);
 
         *newStreamId = streamId;
     }
@@ -556,6 +563,84 @@
     return res;
 }
 
+binder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
+        const hardware::camera2::params::OutputConfiguration &outputConfiguration,
+        /*out*/
+        int* newStreamId) {
+    int width, height, format, surfaceType;
+    int32_t consumerUsage;
+    android_dataspace dataSpace;
+    status_t err;
+    binder::Status res;
+
+    if (!mDevice.get()) {
+        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
+    }
+
+    // Infer the surface info for deferred surface stream creation.
+    width = outputConfiguration.getWidth();
+    height = outputConfiguration.getHeight();
+    surfaceType = outputConfiguration.getSurfaceType();
+    format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+    dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
+    // Hardcode consumer usage flags: SurfaceView--0x900, SurfaceTexture--0x100.
+    consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
+    if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
+        consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
+    }
+    int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
+    err = mDevice->createStream(/*surface*/nullptr, width, height, format, dataSpace,
+            static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
+            &streamId, outputConfiguration.getSurfaceSetID(), consumerUsage);
+
+    if (err != OK) {
+        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
+                "Camera %d: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
+                mCameraId, width, height, format, dataSpace, strerror(-err), err);
+    } else {
+        // Can not add streamId to mStreamMap here, as the surface is deferred. Add it to
+        // a separate list to track. Once the deferred surface is set, this id will be
+        // relocated to mStreamMap.
+        mDeferredStreams.push_back(streamId);
+
+        ALOGV("%s: Camera %d: Successfully created a new stream ID %d for a deferred surface"
+                " (%d x %d) stream with format 0x%x.",
+              __FUNCTION__, mCameraId, streamId, width, height, format);
+
+        // Set transform flags to ensure preview to be rotated correctly.
+        res = setStreamTransformLocked(streamId);
+
+        *newStreamId = streamId;
+    }
+    return res;
+}
+
+binder::Status CameraDeviceClient::setStreamTransformLocked(int streamId) {
+    int32_t transform = 0;
+    status_t err;
+    binder::Status res;
+
+    if (!mDevice.get()) {
+        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
+    }
+
+    err = getRotationTransformLocked(&transform);
+    if (err != OK) {
+        // Error logged by getRotationTransformLocked.
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
+                "Unable to calculate rotation transform for new stream");
+    }
+
+    err = mDevice->setStreamTransform(streamId, transform);
+    if (err != OK) {
+        String8 msg = String8::format("Failed to set stream transform (stream id %d)",
+                streamId);
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+    }
+
+    return res;
+}
 
 binder::Status CameraDeviceClient::createInputStream(
         int width, int height, int format,
@@ -934,6 +1019,76 @@
     return res;
 }
 
+binder::Status CameraDeviceClient::setDeferredConfiguration(int32_t streamId,
+        const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
+    ATRACE_CALL();
+
+    binder::Status res;
+    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
+
+    Mutex::Autolock icl(mBinderSerializationLock);
+
+    sp<IGraphicBufferProducer> bufferProducer = outputConfiguration.getGraphicBufferProducer();
+
+    // Client code should guarantee that the surface is from SurfaceView or SurfaceTexture.
+    if (bufferProducer == NULL) {
+        ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
+    }
+    // Check if this stram id is one of the deferred streams
+    ssize_t index = NAME_NOT_FOUND;
+    for (size_t i = 0; i < mDeferredStreams.size(); i++) {
+        if (streamId == mDeferredStreams[i]) {
+            index = i;
+            break;
+        }
+    }
+    if (index == NAME_NOT_FOUND) {
+        String8 msg = String8::format("Camera %d: deferred surface is set to a unknown stream"
+                "(ID %d)", mCameraId, streamId);
+        ALOGW("%s: %s", __FUNCTION__, msg.string());
+        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+    }
+
+    if (!mDevice.get()) {
+        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
+    }
+
+    // Don't create multiple streams for the same target surface
+    {
+        ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
+        if (index != NAME_NOT_FOUND) {
+            String8 msg = String8::format("Camera %d: Surface already has a stream created "
+                    " for it (ID %zd)", mCameraId, index);
+            ALOGW("%s: %s", __FUNCTION__, msg.string());
+            return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
+        }
+    }
+
+    status_t err;
+
+    // Always set to async, as we know the deferred surface is for preview streaming.
+    sp<Surface> consumerSurface = new Surface(bufferProducer, /*useAsync*/true);
+
+    // Finish the deferred stream configuration with the surface.
+    err = mDevice->setConsumerSurface(streamId, consumerSurface);
+    if (err == OK) {
+        sp<IBinder> binder = IInterface::asBinder(bufferProducer);
+        mStreamMap.add(binder, streamId);
+        mDeferredStreams.removeItemsAt(index);
+    } else if (err == NO_INIT) {
+        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                "Camera %d: Deferred surface is invalid: %s (%d)",
+                mCameraId, strerror(-err), err);
+    } else {
+        res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
+                "Camera %d: Error setting output stream deferred surface: %s (%d)",
+                mCameraId, strerror(-err), err);
+    }
+
+    return res;
+}
+
 status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
     return BasicClient::dump(fd, args);
 }
@@ -959,6 +1114,11 @@
         for (size_t i = 0; i < mStreamMap.size(); i++) {
             result.appendFormat("      Stream %d\n", mStreamMap.valueAt(i));
         }
+    } else if (!mDeferredStreams.isEmpty()) {
+        result.append("    Current deferred surface output stream IDs:\n");
+        for (auto& streamId : mDeferredStreams) {
+            result.appendFormat("      Stream %d\n", streamId);
+        }
     } else {
         result.append("    No output streams configured.\n");
     }
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index d792b7d..dde23fb 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -131,6 +131,10 @@
     // Prepare stream by preallocating up to maxCount of its buffers
     virtual binder::Status prepare2(int32_t maxCount, int32_t streamId);
 
+    // Set the deferred surface for a stream.
+    virtual binder::Status setDeferredConfiguration(int32_t streamId,
+            const hardware::camera2::params::OutputConfiguration &outputConfiguration);
+
     /**
      * Interface used by CameraService
      */
@@ -188,6 +192,15 @@
     // Find the square of the euclidean distance between two points
     static int64_t euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
 
+    // Create an output stream with surface deferred for future.
+    binder::Status createDeferredSurfaceStreamLocked(
+            const hardware::camera2::params::OutputConfiguration &outputConfiguration,
+            int* newStreamId = NULL);
+
+    // Set the stream transform flags to automatically rotate the camera stream for preview use
+    // cases.
+    binder::Status setStreamTransformLocked(int streamId);
+
     // Find the closest dimensions for a given format in available stream configurations with
     // a width <= ROUNDING_WIDTH_CAP
     static const int32_t ROUNDING_WIDTH_CAP = 1920;
@@ -213,6 +226,10 @@
 
     int32_t mRequestIdCounter;
 
+    // The list of output streams whose surfaces are deferred. We have to track them separately
+    // as there are no surfaces available and can not be put into mStreamMap. Once the deferred
+    // Surface is configured, the stream id will be moved to mStreamMap.
+    Vector<int32_t> mDeferredStreams;
 };
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 35ec531..8707f2a 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -110,7 +110,8 @@
     virtual status_t createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
-            int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID) = 0;
+            int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
+            uint32_t consumerUsage = 0) = 0;
 
     /**
      * Create an input stream of width, height, and format.
@@ -312,6 +313,12 @@
      * Get the HAL device version.
      */
     virtual uint32_t getDeviceVersion() = 0;
+
+    /**
+     * Set the deferred consumer surface and finish the rest of the stream configuration.
+     */
+    virtual status_t setConsumerSurface(int streamId, sp<Surface> consumer) = 0;
+
 };
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 96f9338..bbe7317 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -990,12 +990,13 @@
 
 status_t Camera3Device::createStream(sp<Surface> consumer,
         uint32_t width, uint32_t height, int format, android_dataspace dataSpace,
-        camera3_stream_rotation_t rotation, int *id, int streamSetId) {
+        camera3_stream_rotation_t rotation, int *id, int streamSetId, uint32_t consumerUsage) {
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
-    ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d",
-            mId, mNextStreamId, width, height, format, dataSpace, rotation);
+    ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
+            " consumer usage 0x%x", mId, mNextStreamId, width, height, format, dataSpace, rotation,
+            consumerUsage);
 
     status_t res;
     bool wasActive = false;
@@ -1032,6 +1033,19 @@
     if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2) {
         streamSetId = CAMERA3_STREAM_SET_ID_INVALID;
     }
+
+    // HAL3.1 doesn't support deferred consumer stream creation as it requires buffer registration
+    // which requires a consumer surface to be available.
+    if (consumer == nullptr && mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
+        ALOGE("HAL3.1 doesn't support deferred consumer stream creation");
+        return BAD_VALUE;
+    }
+
+    if (consumer == nullptr && format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+        ALOGE("Deferred consumer stream creation only support IMPLEMENTATION_DEFINED format");
+        return BAD_VALUE;
+    }
+
     // Use legacy dataspace values for older HALs
     if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_3) {
         dataSpace = mapToLegacyDataspace(dataSpace);
@@ -1063,6 +1077,10 @@
         newStream = new Camera3OutputStream(mNextStreamId, consumer,
                 width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
                 mTimestampOffset, streamSetId);
+    } else if (consumer == nullptr) {
+        newStream = new Camera3OutputStream(mNextStreamId,
+                width, height, format, consumerUsage, dataSpace, rotation,
+                mTimestampOffset, streamSetId);
     } else {
         newStream = new Camera3OutputStream(mNextStreamId, consumer,
                 width, height, format, dataSpace, rotation,
@@ -1722,6 +1740,44 @@
     }
 }
 
+status_t Camera3Device::setConsumerSurface(int streamId, sp<Surface> consumer) {
+    ATRACE_CALL();
+    ALOGV("%s: Camera %d: set consumer surface for stream %d", __FUNCTION__, mId, streamId);
+    Mutex::Autolock il(mInterfaceLock);
+    Mutex::Autolock l(mLock);
+
+    if (consumer == nullptr) {
+        CLOGE("Null consumer is passed!");
+        return BAD_VALUE;
+    }
+
+    ssize_t idx = mOutputStreams.indexOfKey(streamId);
+    if (idx == NAME_NOT_FOUND) {
+        CLOGE("Stream %d is unknown", streamId);
+        return idx;
+    }
+    sp<Camera3OutputStreamInterface> stream = mOutputStreams[idx];
+    status_t res = stream->setConsumer(consumer);
+    if (res != OK) {
+        CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
+        return res;
+    }
+
+    if (!stream->isConfiguring()) {
+        CLOGE("Stream %d was already fully configured.", streamId);
+        return INVALID_OPERATION;
+    }
+
+    res = stream->finishConfiguration(mHal3Device);
+    if (res != OK) {
+        SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
+                stream->getId(), strerror(-res), res);
+        return res;
+    }
+
+    return OK;
+}
+
 /**
  * Camera3Device private methods
  */
@@ -1781,6 +1837,13 @@
         sp<Camera3OutputStreamInterface> stream =
                 mOutputStreams.editValueAt(idx);
 
+        // It is illegal to include a deferred consumer output stream into a request
+        if (stream->isConsumerConfigurationDeferred()) {
+            CLOGE("Stream %d hasn't finished configuration yet due to deferred consumer",
+                    stream->getId());
+            return NULL;
+        }
+
         // Lazy completion of stream configuration (allocation/registration)
         // on first use
         if (stream->isConfiguring()) {
@@ -1948,7 +2011,7 @@
     for (size_t i = 0; i < mOutputStreams.size(); i++) {
         sp<Camera3OutputStreamInterface> outputStream =
             mOutputStreams.editValueAt(i);
-        if (outputStream->isConfiguring()) {
+        if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
             res = outputStream->finishConfiguration(mHal3Device);
             if (res != OK) {
                 CLOGE("Can't finish configuring output stream %d: %s (%d)",
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 2aca57d..fe5f217 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -95,11 +95,14 @@
 
     // Actual stream creation/deletion is delayed until first request is submitted
     // If adding streams while actively capturing, will pause device before adding
-    // stream, reconfiguring device, and unpausing.
+    // stream, reconfiguring device, and unpausing. If the client create a stream
+    // with nullptr consumer surface, the client must then call setConsumer()
+    // and finish the stream configuration before starting output streaming.
     virtual status_t createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
-            int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID);
+            int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
+            uint32_t consumerUsage = 0);
     virtual status_t createInputStream(
             uint32_t width, uint32_t height, int format,
             int *id);
@@ -160,6 +163,12 @@
     // Methods called by subclasses
     void             notifyStatus(bool idle); // updates from StatusTracker
 
+    /**
+     * Set the deferred consumer surface to the output stream and finish the deferred
+     * consumer configuration.
+     */
+    virtual status_t setConsumerSurface(int streamId, sp<Surface> consumer);
+
   private:
     static const size_t        kDumpLockAttempts  = 10;
     static const size_t        kDumpSleepDuration = 100000; // 0.10 sec
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
index 6354ef7..5123785 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
@@ -103,6 +103,15 @@
     return false;
 }
 
+bool Camera3DummyStream::isConsumerConfigurationDeferred() const {
+    return false;
+}
+
+status_t Camera3DummyStream::setConsumer(sp<Surface> consumer) {
+    ALOGE("%s: Stream %d: Dummy stream doesn't support set consumer surface %p!",
+            __FUNCTION__, mId, consumer.get());
+    return INVALID_OPERATION;
+}
 }; // namespace camera3
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h
index 7b48daa..639619e 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.h
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h
@@ -61,6 +61,16 @@
      */
     bool isVideoStream() const;
 
+    /**
+     * Return if the consumer configuration of this stream is deferred.
+     */
+    virtual bool isConsumerConfigurationDeferred() const;
+
+    /**
+     * Set the consumer surface to the output stream.
+     */
+    virtual status_t setConsumer(sp<Surface> consumer);
+
   protected:
 
     /**
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index d09951a..bc8f631 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -42,7 +42,8 @@
         mTransform(0),
         mTraceFirstBuffer(true),
         mUseBufferManager(false),
-        mTimestampOffset(timestampOffset) {
+        mTimestampOffset(timestampOffset),
+        mConsumerUsage(0) {
 
     if (mConsumer == NULL) {
         ALOGE("%s: Consumer is NULL!", __FUNCTION__);
@@ -66,7 +67,8 @@
         mTraceFirstBuffer(true),
         mUseMonoTimestamp(false),
         mUseBufferManager(false),
-        mTimestampOffset(timestampOffset) {
+        mTimestampOffset(timestampOffset),
+        mConsumerUsage(0) {
 
     if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
         ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
@@ -84,6 +86,39 @@
     }
 }
 
+Camera3OutputStream::Camera3OutputStream(int id,
+        uint32_t width, uint32_t height, int format,
+        uint32_t consumerUsage, android_dataspace dataSpace,
+        camera3_stream_rotation_t rotation, nsecs_t timestampOffset, int setId) :
+        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
+                            /*maxSize*/0, format, dataSpace, rotation, setId),
+        mConsumer(nullptr),
+        mTransform(0),
+        mTraceFirstBuffer(true),
+        mUseBufferManager(false),
+        mTimestampOffset(timestampOffset),
+        mConsumerUsage(consumerUsage) {
+    // Deferred consumer only support preview surface format now.
+    if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+        ALOGE("%s: Deferred consumer only supports IMPLEMENTATION_DEFINED format now!",
+                __FUNCTION__);
+        mState = STATE_ERROR;
+    }
+
+    // Sanity check for the consumer usage flag.
+    if ((consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) == 0 &&
+            (consumerUsage & GraphicBuffer::USAGE_HW_COMPOSER) == 0) {
+        ALOGE("%s: Deferred consumer usage flag is illegal (0x%x)!", __FUNCTION__, consumerUsage);
+        mState = STATE_ERROR;
+    }
+
+    mConsumerName = String8("Deferred");
+    if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
+        mBufferReleasedListener = new BufferReleasedListener(this);
+    }
+
+}
+
 Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
                                          uint32_t width, uint32_t height,
                                          int format,
@@ -96,7 +131,8 @@
         mTransform(0),
         mTraceFirstBuffer(true),
         mUseMonoTimestamp(false),
-        mUseBufferManager(false) {
+        mUseBufferManager(false),
+        mConsumerUsage(0) {
 
     if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
         mBufferReleasedListener = new BufferReleasedListener(this);
@@ -475,11 +511,16 @@
         return res;
     }
 
+    // Stream configuration was not finished (can only be in STATE_IN_CONFIG or STATE_CONSTRUCTED
+    // state), don't need change the stream state, return OK.
+    if (mConsumer == nullptr) {
+        return OK;
+    }
+
     ALOGV("%s: disconnecting stream %d from native window", __FUNCTION__, getId());
 
     res = native_window_api_disconnect(mConsumer.get(),
                                        NATIVE_WINDOW_API_CAMERA);
-
     /**
      * This is not an error. if client calling process dies, the window will
      * also die and all calls to it will return DEAD_OBJECT, thus it's already
@@ -521,6 +562,12 @@
 
     status_t res;
     int32_t u = 0;
+    if (mConsumer == nullptr) {
+        // mConsumerUsage was sanitized before the Camera3OutputStream was constructed.
+        *usage = mConsumerUsage;
+        return OK;
+    }
+
     res = static_cast<ANativeWindow*>(mConsumer.get())->query(mConsumer.get(),
             NATIVE_WINDOW_CONSUMER_USAGE_BITS, &u);
 
@@ -556,7 +603,7 @@
 status_t Camera3OutputStream::setBufferManager(sp<Camera3BufferManager> bufferManager) {
     Mutex::Autolock l(mLock);
     if (mState != STATE_CONSTRUCTED) {
-        ALOGE("%s: this method can only be called when stream in in CONSTRUCTED state.",
+        ALOGE("%s: this method can only be called when stream in CONSTRUCTED state.",
                 __FUNCTION__);
         return INVALID_OPERATION;
     }
@@ -622,6 +669,26 @@
     return OK;
 }
 
+bool Camera3OutputStream::isConsumerConfigurationDeferred() const {
+    Mutex::Autolock l(mLock);
+    return mConsumer == nullptr;
+}
+
+status_t Camera3OutputStream::setConsumer(sp<Surface> consumer) {
+    if (consumer == nullptr) {
+        ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
+    if (mConsumer != nullptr) {
+        ALOGE("%s: consumer surface was already set!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
+    mConsumer = consumer;
+    return OK;
+}
+
 bool Camera3OutputStream::isConsumedByHWComposer() const {
     uint32_t usage = 0;
     status_t res = getEndpointUsage(&usage);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 7d28b05..5507cfc 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -94,6 +94,16 @@
             android_dataspace dataSpace, camera3_stream_rotation_t rotation,
             nsecs_t timestampOffset, int setId = CAMERA3_STREAM_SET_ID_INVALID);
 
+    /**
+     * Set up a stream with deferred consumer for formats that have 2 dimensions, such as
+     * RAW and YUV. The consumer must be set before using this stream for output. A valid
+     * stream set id needs to be set to support buffer sharing between multiple streams.
+     */
+    Camera3OutputStream(int id, uint32_t width, uint32_t height, int format,
+            uint32_t consumerUsage, android_dataspace dataSpace,
+            camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
+            int setId = CAMERA3_STREAM_SET_ID_INVALID);
+
     virtual ~Camera3OutputStream();
 
     /**
@@ -117,6 +127,16 @@
      */
     bool isConsumedByHWComposer() const;
 
+    /**
+     * Return if the consumer configuration of this stream is deferred.
+     */
+    virtual bool isConsumerConfigurationDeferred() const;
+
+    /**
+     * Set the consumer surface to the output stream.
+     */
+    virtual status_t setConsumer(sp<Surface> consumer);
+
     class BufferReleasedListener : public BnProducerListener {
         public:
           BufferReleasedListener(wp<Camera3OutputStream> parent) : mParent(parent) {}
@@ -159,6 +179,7 @@
     virtual status_t disconnectLocked();
 
     sp<Surface> mConsumer;
+
   private:
     int               mTransform;
 
@@ -195,6 +216,12 @@
     nsecs_t mTimestampOffset;
 
     /**
+     * Consumer end point usage flag set by the constructor for the deferred
+     * consumer case.
+     */
+    uint32_t    mConsumerUsage;
+
+    /**
      * Internal Camera3Stream interface
      */
     virtual status_t getBufferLocked(camera3_stream_buffer *buffer);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index 50dce55..3f83c89 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -41,6 +41,16 @@
     virtual bool isVideoStream() const = 0;
 
     /**
+     * Return if the consumer configuration of this stream is deferred.
+     */
+    virtual bool isConsumerConfigurationDeferred() const = 0;
+
+    /**
+     * Set the consumer surface to the output stream.
+     */
+    virtual status_t setConsumer(sp<Surface> consumer) = 0;
+
+    /**
      * Detach an unused buffer from the stream.
      *
      * buffer must be non-null; fenceFd may null, and if it is non-null, but
@@ -49,7 +59,6 @@
      *
      */
     virtual status_t detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd) = 0;
-
 };
 
 } // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 96d62d4..3ffd9d1 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -55,7 +55,7 @@
     mMaxSize(maxSize),
     mState(STATE_CONSTRUCTED),
     mStatusId(StatusTracker::NO_STATUS_ID),
-    mStreamUnpreparable(false),
+    mStreamUnpreparable(true),
     mOldUsage(0),
     mOldMaxBuffers(0),
     mPrepared(false),
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 0755700..1ff215d 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -175,7 +175,8 @@
      *   OK on a successful configuration
      *   NO_INIT in case of a serious error from the HAL device
      *   NO_MEMORY in case of an error registering buffers
-     *   INVALID_OPERATION in case connecting to the consumer failed
+     *   INVALID_OPERATION in case connecting to the consumer failed or consumer
+     *       doesn't exist yet.
      */
     status_t         finishConfiguration(camera3_device *hal3Device);