merge in lmp-release history after reset to 720d9297f72f8b5c006ff46e7cb69f2e1d4b641f
diff --git a/audio_policy.conf b/audio_policy.conf
index 3f7ac24..f1c1c96 100644
--- a/audio_policy.conf
+++ b/audio_policy.conf
@@ -30,28 +30,21 @@
         sampling_rates 44100|48000
         channel_masks AUDIO_CHANNEL_OUT_STEREO
         formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL
+        devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_LINE
         flags AUDIO_OUTPUT_FLAG_PRIMARY
       }
       deep_buffer {
          sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000
          channel_masks AUDIO_CHANNEL_OUT_STEREO
          formats AUDIO_FORMAT_PCM_16_BIT
-         devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL
+         devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_LINE
          flags AUDIO_OUTPUT_FLAG_DEEP_BUFFER
       }
-      hdmi {
-        sampling_rates 44100|48000
-        channel_masks dynamic
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_OUT_AUX_DIGITAL
-        flags AUDIO_OUTPUT_FLAG_DIRECT
-      }
       compress_offload {
         sampling_rates 8000|11025|16000|22050|32000|44100|48000
         channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO
         formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_AAC
-        devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE
+        devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE
         flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING
       }
     }
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.cpp b/camera/QCamera2/HAL3/QCamera3Channel.cpp
old mode 100644
new mode 100755
index e5cc688..bf934ba
--- a/camera/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Channel.cpp
@@ -532,6 +532,7 @@
     } else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
          streamFormat = CALLBACK_FORMAT;
     } else if (mCamera3Stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
+         mCamera3Stream->format == HAL_PIXEL_FORMAT_RAW10 ||
          mCamera3Stream->format == HAL_PIXEL_FORMAT_RAW16) {
          // Bayer pattern doesn't matter here.
          // All CAMIF raw format uses 10bit.
@@ -867,7 +868,7 @@
                         mIsRaw16(raw_16)
 {
     char prop[PROPERTY_VALUE_MAX];
-    property_get("persist.camera.raw.dump", prop, "0");
+    property_get("persist.camera.raw.debug.dump", prop, "0");
     mRawDump = atoi(prop);
 }
 
@@ -957,6 +958,230 @@
 }
 
 /*************************************************************************************/
+// RAW Dump Channel related functions
+
+int QCamera3RawDumpChannel::kMaxBuffers = 3;
+/*===========================================================================
+ * FUNCTION   : QCamera3RawDumpChannel
+ *
+ * DESCRIPTION: Constructor for RawDumpChannel
+ *
+ * PARAMETERS :
+ *   @cam_handle    : Handle for Camera
+ *   @cam_ops       : Function pointer table
+ *   @rawDumpSize   : Dimensions for the Raw stream
+ *   @paddinginfo   : Padding information for stream
+ *   @userData      : Cookie for parent
+ *   @pp mask       : PP feature mask for this stream
+ *
+ * RETURN           : NA
+ *==========================================================================*/
+QCamera3RawDumpChannel::QCamera3RawDumpChannel(uint32_t cam_handle,
+                    mm_camera_ops_t *cam_ops,
+                    cam_dimension_t rawDumpSize,
+                    cam_padding_info_t *paddingInfo,
+                    void *userData,
+                    uint32_t postprocess_mask) :
+                        QCamera3Channel(cam_handle, cam_ops, NULL,
+                                paddingInfo, postprocess_mask, userData),
+                        mDim(rawDumpSize),
+                        mMemory(NULL)
+{
+    char prop[PROPERTY_VALUE_MAX];
+    property_get("persist.camera.raw.dump", prop, "0");
+    mRawDump = atoi(prop);
+}
+
+/*===========================================================================
+ * FUNCTION   : QCamera3RawDumpChannel
+ *
+ * DESCRIPTION: Destructor for RawDumpChannel
+ *
+ * PARAMETERS :
+ *
+ * RETURN           : NA
+ *==========================================================================*/
+
+QCamera3RawDumpChannel::~QCamera3RawDumpChannel()
+{
+}
+
+/*===========================================================================
+ * FUNCTION   : dumpRawSnapshot
+ *
+ * DESCRIPTION: Helper function to dump Raw frames
+ *
+ * PARAMETERS :
+ *  @frame      : stream buf frame to be dumped
+ *
+ *  RETURN      : NA
+ *==========================================================================*/
+void QCamera3RawDumpChannel::dumpRawSnapshot(mm_camera_buf_def_t *frame)
+{
+    QCamera3Stream *stream = getStreamByIndex(0);
+    char buf[128];
+    struct timeval tv;
+    struct tm *timeinfo;
+
+    cam_dimension_t dim;
+    memset(&dim, 0, sizeof(dim));
+    stream->getFrameDimension(dim);
+
+    cam_frame_len_offset_t offset;
+    memset(&offset, 0, sizeof(cam_frame_len_offset_t));
+    stream->getFrameOffset(offset);
+
+    gettimeofday(&tv, NULL);
+    timeinfo = localtime(&tv.tv_sec);
+
+    memset(buf, 0, sizeof(buf));
+    snprintf(buf, sizeof(buf),
+                 "/data/%04d-%02d-%02d-%02d-%02d-%02d-%06ld_%d_%dx%d.raw",
+                 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1,
+                 timeinfo->tm_mday, timeinfo->tm_hour,
+                 timeinfo->tm_min, timeinfo->tm_sec,tv.tv_usec,
+                 frame->frame_idx, dim.width, dim.height);
+
+    int file_fd = open(buf, O_RDWR| O_CREAT, 0777);
+    if (file_fd >= 0) {
+        int written_len = write(file_fd, frame->buffer, offset.frame_len);
+        CDBG("%s: written number of bytes %d", __func__, written_len);
+        close(file_fd);
+    } else {
+        ALOGE("%s: failed to open file to dump image", __func__);
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : streamCbRoutine
+ *
+ * DESCRIPTION: Callback routine invoked for each frame generated for
+ *              Rawdump channel
+ *
+ * PARAMETERS :
+ *   @super_frame  : stream buf frame generated
+ *   @stream       : Underlying Stream object cookie
+ *
+ * RETURN          : NA
+ *==========================================================================*/
+void QCamera3RawDumpChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
+                                                QCamera3Stream *stream)
+{
+    CDBG("%s: E",__func__);
+    if (super_frame == NULL || super_frame->num_bufs != 1) {
+        ALOGE("%s: super_frame is not valid", __func__);
+        return;
+    }
+
+    if (mRawDump)
+        dumpRawSnapshot(super_frame->bufs[0]);
+
+    bufDone(super_frame);
+    free(super_frame);
+}
+
+/*===========================================================================
+ * FUNCTION   : getStreamBufs
+ *
+ * DESCRIPTION: Callback function provided to interface to get buffers.
+ *
+ * PARAMETERS :
+ *   @len       : Length of each buffer to be allocated
+ *
+ * RETURN     : NULL on buffer allocation failure
+ *              QCamera3Memory object on sucess
+ *==========================================================================*/
+QCamera3Memory* QCamera3RawDumpChannel::getStreamBufs(uint32_t len)
+{
+    int rc;
+    mMemory = new QCamera3HeapMemory();
+
+    if (!mMemory) {
+        ALOGE("%s: unable to create heap memory", __func__);
+        return NULL;
+    }
+    rc = mMemory->allocate(kMaxBuffers, len, true);
+    if (rc < 0) {
+        ALOGE("%s: unable to allocate heap memory", __func__);
+        delete mMemory;
+        mMemory = NULL;
+        return NULL;
+    }
+    return mMemory;
+}
+
+/*===========================================================================
+ * FUNCTION   : putStreamBufs
+ *
+ * DESCRIPTION: Callback function provided to interface to return buffers.
+ *              Although no handles are actually returned, implicitl assumption
+ *              that interface will no longer use buffers and channel can
+ *              deallocated if necessary.
+ *
+ * PARAMETERS : NA
+ *
+ * RETURN     : NA
+ *==========================================================================*/
+void QCamera3RawDumpChannel::putStreamBufs()
+{
+    mMemory->deallocate();
+    delete mMemory;
+    mMemory = NULL;
+}
+
+/*===========================================================================
+ * FUNCTION : request
+ *
+ * DESCRIPTION: Request function used as trigger
+ *
+ * PARAMETERS :
+ * @recvd_frame : buffer- this will be NULL since this is internal channel
+ * @frameNumber : Undefined again since this is internal stream
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCamera3RawDumpChannel::request(buffer_handle_t * /*buffer*/,
+                                                uint32_t /*frameNumber*/)
+{
+    if (!m_bIsActive) {
+        return QCamera3Channel::start();
+    }
+    else
+        return 0;
+}
+
+/*===========================================================================
+ * FUNCTION : intialize
+ *
+ * DESCRIPTION: Initializes channel params and creates underlying stream
+ *
+ * PARAMETERS : NA
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCamera3RawDumpChannel::initialize()
+{
+    int32_t rc;
+
+    rc = init(NULL, NULL);
+    if (rc < 0) {
+        ALOGE("%s: init failed", __func__);
+        return rc;
+    }
+
+    rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_RAW,
+        CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG, mDim, kMaxBuffers,
+        mPostProcMask);
+    if (rc < 0) {
+        ALOGE("%s: addStream failed", __func__);
+    }
+    return rc;
+}
+/*************************************************************************************/
 
 /*===========================================================================
  * FUNCTION   : jpegEvtHandle
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.h b/camera/QCamera2/HAL3/QCamera3Channel.h
index 2e25ced..3c62104 100644
--- a/camera/QCamera2/HAL3/QCamera3Channel.h
+++ b/camera/QCamera2/HAL3/QCamera3Channel.h
@@ -217,6 +217,39 @@
     void convertToRaw16(mm_camera_buf_def_t *frame);
 };
 
+/*
+ * QCamera3RawDumpChannel is for internal use only for Raw dump
+ */
+
+class QCamera3RawDumpChannel : public QCamera3Channel
+{
+public:
+    QCamera3RawDumpChannel(uint32_t cam_handle,
+                    mm_camera_ops_t *cam_ops,
+                    cam_dimension_t rawDumpSize,
+                    cam_padding_info_t *paddingInfo,
+                    void *userData,
+                    uint32_t postprocess_mask);
+    virtual ~QCamera3RawDumpChannel();
+    virtual int32_t initialize();
+    virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
+                            QCamera3Stream *stream);
+    virtual QCamera3Memory *getStreamBufs(uint32_t le);
+    virtual void putStreamBufs();
+    virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/)
+            { return NO_ERROR; };
+    virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
+    void dumpRawSnapshot(mm_camera_buf_def_t *frame);
+
+public:
+    static int kMaxBuffers;
+    cam_dimension_t mDim;
+
+private:
+    bool mRawDump;
+    QCamera3HeapMemory *mMemory;
+};
+
 /* QCamera3PicChannel is for JPEG stream, which contains a YUV stream generated
  * by the hardware, and encoded to a JPEG stream */
 class QCamera3PicChannel : public QCamera3Channel
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
old mode 100644
new mode 100755
index 6d69ab5..4d96d64
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -66,10 +66,6 @@
 const camera_metadata_t *gStaticMetadata[MM_CAMERA_MAX_NUM_SENSORS];
 volatile uint32_t gCamHal3LogLevel = 1;
 
-pthread_mutex_t QCamera3HardwareInterface::mCameraSessionLock =
-    PTHREAD_MUTEX_INITIALIZER;
-unsigned int QCamera3HardwareInterface::mCameraSessionActive = 0;
-
 const QCamera3HardwareInterface::QCameraPropMap QCamera3HardwareInterface::CDS_MAP [] = {
     {"On",  CAM_CDS_MODE_ON},
     {"Off", CAM_CDS_MODE_OFF},
@@ -249,6 +245,7 @@
       mPictureChannel(NULL),
       mRawChannel(NULL),
       mSupportChannel(NULL),
+      mRawDumpChannel(NULL),
       mFirstRequest(false),
       mFlush(false),
       mParamHeap(NULL),
@@ -287,6 +284,12 @@
         ALOGE("%s: %s module not found", __func__, POWER_HARDWARE_MODULE_ID);
     }
 #endif
+
+    char prop[PROPERTY_VALUE_MAX];
+    property_get("persist.camera.raw.dump", prop, "0");
+    mEnableRawDump = atoi(prop);
+    if (mEnableRawDump)
+        CDBG("%s: Raw dump from Camera HAL enabled", __func__);
 }
 
 /*===========================================================================
@@ -303,6 +306,11 @@
     CDBG("%s: E", __func__);
     /* We need to stop all streams before deleting any stream */
 
+
+    if (mRawDumpChannel) {
+        mRawDumpChannel->stop();
+    }
+
     // NOTE: 'camera3_stream_t *' objects are already freed at
     //        this stage by the framework
     for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
@@ -327,6 +335,10 @@
         mSupportChannel = NULL;
     }
 
+    if (mRawDumpChannel) {
+        delete mRawDumpChannel;
+        mRawDumpChannel = NULL;
+    }
     mPictureChannel = NULL;
 
     /* Clean up all channels */
@@ -371,13 +383,6 @@
 int QCamera3HardwareInterface::openCamera(struct hw_device_t **hw_device)
 {
     int rc = 0;
-    pthread_mutex_lock(&mCameraSessionLock);
-    if (mCameraSessionActive) {
-        ALOGE("%s: multiple simultaneous camera instance not supported", __func__);
-        pthread_mutex_unlock(&mCameraSessionLock);
-        return -EUSERS;
-    }
-
     if (mCameraOpened) {
         *hw_device = NULL;
         return PERMISSION_DENIED;
@@ -386,7 +391,6 @@
     rc = openCamera();
     if (rc == 0) {
         *hw_device = &mCameraDevice.common;
-        mCameraSessionActive = 1;
     } else
         *hw_device = NULL;
 
@@ -400,7 +404,6 @@
         }
     }
 #endif
-    pthread_mutex_unlock(&mCameraSessionLock);
     return rc;
 }
 
@@ -532,6 +535,41 @@
         return BAD_VALUE;
     }
 
+    pthread_mutex_lock(&mMutex);
+
+    /* Check whether we have video stream */
+    m_bIs4KVideo = false;
+    m_bIsVideo = false;
+    bool isZsl = false;
+    size_t videoWidth = 0;
+    size_t videoHeight = 0;
+    /* Check whether we have zsl stream or 4k video case */
+    for (size_t i = 0; i < streamList->num_streams; i++) {
+        camera3_stream_t *newStream = streamList->streams[i];
+        if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
+                newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED){
+            isZsl = true;
+        }
+        if ((HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) &&
+                (newStream->usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER)) {
+            m_bIsVideo = true;
+            if ((VIDEO_4K_WIDTH <= newStream->width) &&
+                    (VIDEO_4K_HEIGHT <= newStream->height)) {
+                videoWidth = newStream->width;
+                videoHeight = newStream->height;
+                m_bIs4KVideo = true;
+            }
+        }
+    }
+
+    if (isZsl && m_bIsVideo) {
+        ALOGE("%s: Currently invalid configuration ZSL&Video!", __func__);
+        pthread_mutex_unlock(&mMutex);
+        return -EINVAL;
+    }
+
+    pthread_mutex_unlock(&mMutex);
+
     /* first invalidate all the steams in the mStreamList
      * if they appear again, they will be validated */
     for (List<stream_info_t*>::iterator it = mStreamInfo.begin();
@@ -540,14 +578,21 @@
         channel->stop();
         (*it)->status = INVALID;
     }
+
+    if (mRawDumpChannel) {
+        mRawDumpChannel->stop();
+        delete mRawDumpChannel;
+        mRawDumpChannel = NULL;
+    }
+
+    if (mSupportChannel)
+        mSupportChannel->stop();
     if (mMetadataChannel) {
         /* If content of mStreamInfo is not 0, there is metadata stream */
         mMetadataChannel->stop();
     }
 
     pthread_mutex_lock(&mMutex);
-
-    bool isZsl = false;
     camera3_stream_t *inputStream = NULL;
     camera3_stream_t *jpegStream = NULL;
     cam_stream_size_info_t stream_config_info;
@@ -599,6 +644,10 @@
         delete mMetadataChannel;
         mMetadataChannel = NULL;
     }
+    if (mSupportChannel) {
+        delete mSupportChannel;
+        mSupportChannel = NULL;
+    }
 
     //Create metadata channel and initialize it
     mMetadataChannel = new QCamera3MetadataChannel(mCameraHandle->camera_handle,
@@ -622,6 +671,7 @@
     /* Create dummy stream if there is one single raw stream */
     if (streamList->num_streams == 1 &&
             (streamList->streams[0]->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
+            streamList->streams[0]->format == HAL_PIXEL_FORMAT_RAW10 ||
             streamList->streams[0]->format == HAL_PIXEL_FORMAT_RAW16)) {
         mSupportChannel = new QCamera3SupportChannel(
                 mCameraHandle->camera_handle,
@@ -647,31 +697,7 @@
         }
     }
 
-
-    /* Check whether we have video stream */
-    m_bIs4KVideo = false;
-    m_bIsVideo = false;
-    size_t videoWidth = 0;
-    size_t videoHeight = 0;
-    /* Check whether we have zsl stream or 4k video case */
-    for (size_t i = 0; i < streamList->num_streams; i++) {
-        camera3_stream_t *newStream = streamList->streams[i];
-        if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
-                newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED && jpegStream){
-            isZsl = true;
-        }
-        if ((HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) &&
-                (newStream->usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER)) {
-            m_bIsVideo = true;
-            if ((VIDEO_4K_WIDTH <= newStream->width) &&
-                    (VIDEO_4K_HEIGHT <= newStream->height)) {
-                videoWidth = newStream->width;
-                videoHeight = newStream->height;
-                m_bIs4KVideo = true;
-            }
-        }
-    }
-
+    bool isRawStreamRequested = false;
     /* Allocate channel objects for the requested streams */
     for (size_t i = 0; i < streamList->num_streams; i++) {
         camera3_stream_t *newStream = streamList->streams[i];
@@ -723,7 +749,9 @@
               break;
            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
            case HAL_PIXEL_FORMAT_RAW16:
+           case HAL_PIXEL_FORMAT_RAW10:
               stream_config_info.type[i] = CAM_STREAM_TYPE_RAW;
+              isRawStreamRequested = true;
               break;
            default:
               stream_config_info.type[i] = CAM_STREAM_TYPE_DEFAULT;
@@ -781,6 +809,7 @@
                     break;
                 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
                 case HAL_PIXEL_FORMAT_RAW16:
+                case HAL_PIXEL_FORMAT_RAW10:
                     newStream->max_buffers = QCamera3RawChannel::kMaxBuffers;
                     mRawChannel = new QCamera3RawChannel(
                             mCameraHandle->camera_handle,
@@ -837,6 +866,23 @@
         mPictureChannel->overrideYuvSize(videoWidth, videoHeight);
     }
 
+    //RAW DUMP channel
+    if (mEnableRawDump && isRawStreamRequested == false){
+        cam_dimension_t rawDumpSize;
+        rawDumpSize = getMaxRawSize(mCameraId);
+        mRawDumpChannel = new QCamera3RawDumpChannel(mCameraHandle->camera_handle,
+                                  mCameraHandle->ops,
+                                  rawDumpSize,
+                                  &gCamCapability[mCameraId]->padding_info,
+                                  this, CAM_QCOM_FEATURE_NONE);
+        if (!mRawDumpChannel) {
+            ALOGE("%s: Raw Dump channel cannot be created", __func__);
+            pthread_mutex_unlock(&mMutex);
+            return -ENOMEM;
+        }
+    }
+
+
     int32_t hal_version = CAM_HAL_V3;
     stream_config_info.num_streams = streamList->num_streams;
     if (mSupportChannel) {
@@ -847,6 +893,16 @@
         stream_config_info.num_streams++;
     }
 
+    if (mRawDumpChannel) {
+        cam_dimension_t rawSize;
+        rawSize = getMaxRawSize(mCameraId);
+        stream_config_info.stream_sizes[stream_config_info.num_streams] =
+                rawSize;
+        stream_config_info.type[stream_config_info.num_streams] =
+                CAM_STREAM_TYPE_RAW;
+        stream_config_info.num_streams++;
+    }
+
     // settings/parameters don't carry over for new configureStreams
     memset(mParameters, 0, sizeof(metadata_buffer_t));
 
@@ -1010,6 +1066,7 @@
             if (dimension > maxJpegDim)
                 maxJpegDim = dimension;
         } else if ((*it)->stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
+                (*it)->stream->format == HAL_PIXEL_FORMAT_RAW10 ||
                 (*it)->stream->format == HAL_PIXEL_FORMAT_RAW16) {
             if (dimension > maxRawDim)
                 maxRawDim = dimension;
@@ -1077,6 +1134,7 @@
         if (stream->format == HAL_PIXEL_FORMAT_BLOB)
             hasJpegStream = true;
         else if (stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
+                stream->format == HAL_PIXEL_FORMAT_RAW10 ||
                 stream->format == HAL_PIXEL_FORMAT_RAW16)
             hasRawStream = true;
     }
@@ -1659,6 +1717,18 @@
                 return rc;
             }
         }
+
+        if (mRawDumpChannel) {
+            rc = mRawDumpChannel->initialize();
+            if (rc != NO_ERROR) {
+                ALOGE("%s: Error: Raw Dump Channel init failed", __func__);
+                if (mSupportChannel)
+                    mSupportChannel->stop();
+                mMetadataChannel->stop();
+                pthread_mutex_unlock(&mMutex);
+                return rc;
+            }
+        }
         //Then start them.
         for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
             it != mStreamInfo.end(); it++) {
@@ -1666,6 +1736,27 @@
             CDBG_HIGH("%s: Start Regular Channel mask=%d", __func__, channel->getStreamTypeMask());
             channel->start();
         }
+
+        if (mRawDumpChannel) {
+            CDBG("%s: Starting raw dump stream",__func__);
+            rc = mRawDumpChannel->start();
+            if (rc != NO_ERROR) {
+                ALOGE("%s: Error Starting Raw Dump Channel", __func__);
+                for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
+                      it != mStreamInfo.end(); it++) {
+                    QCamera3Channel *channel =
+                        (QCamera3Channel *)(*it)->stream->priv;
+                    ALOGE("%s: Stopping Regular Channel mask=%d", __func__,
+                        channel->getStreamTypeMask());
+                    channel->stop();
+                }
+                if (mSupportChannel)
+                    mSupportChannel->stop();
+                mMetadataChannel->stop();
+                pthread_mutex_unlock(&mMutex);
+                return rc;
+            }
+        }
     }
 
     uint32_t frameNumber = request->frame_number;
@@ -1712,6 +1803,15 @@
         streamID.streamID[streamID.num_streams] =
             channel->getStreamID(channel->getStreamTypeMask());
         streamID.num_streams++;
+
+
+    }
+
+    if (blob_request && mRawDumpChannel) {
+        CDBG("%s: Trigger Raw based on blob request if Raw dump is enabled", __func__);
+        streamID.streamID[streamID.num_streams] =
+            mRawDumpChannel->getStreamID(mRawDumpChannel->getStreamTypeMask());
+        streamID.num_streams++;
     }
 
     if(request->input_buffer == NULL) {
@@ -1960,6 +2060,9 @@
     if (mSupportChannel) {
         mSupportChannel->stop();
     }
+    if (mRawDumpChannel) {
+        mRawDumpChannel->stop();
+    }
     if (mMetadataChannel) {
         /* If content of mStreamInfo is not 0, there is metadata stream */
         mMetadataChannel->stop();
@@ -2550,6 +2653,62 @@
         camMetadata.update(QCAMERA3_PRIVATEDATA_REPROCESS,
                 privateData, MAX_METADATA_PRIVATE_PAYLOAD_SIZE);
     }
+    if (metadata->is_tuning_params_valid) {
+        uint8_t tuning_meta_data_blob[sizeof(tuning_params_t)];
+        uint8_t *data = (uint8_t*)&tuning_meta_data_blob[0];
+        metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION;
+
+
+        memcpy(data, ((uint8_t*)&metadata->tuning_params.tuning_data_version),
+                sizeof(uint32_t));
+        data += sizeof(uint32_t);
+
+        memcpy(data, ((uint8_t*)&metadata->tuning_params.tuning_sensor_data_size),
+                sizeof(uint32_t));
+        CDBG("tuning_sensor_data_size %d",(int)(*(int *)data));
+        data += sizeof(uint32_t);
+
+        memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size),
+                sizeof(uint32_t));
+        CDBG("tuning_vfe_data_size %d",(int)(*(int *)data));
+        data += sizeof(uint32_t);
+
+        memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size),
+                sizeof(uint32_t));
+        CDBG("tuning_cpp_data_size %d",(int)(*(int *)data));
+        data += sizeof(uint32_t);
+
+        memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_cac_data_size),
+                sizeof(uint32_t));
+        CDBG("tuning_cac_data_size %d",(int)(*(int *)data));
+        data += sizeof(uint32_t);
+
+        metadata->tuning_params.tuning_mod3_data_size = 0;
+        memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_mod3_data_size),
+                sizeof(uint32_t));
+        CDBG("tuning_mod3_data_size %d",(int)(*(int *)data));
+        data += sizeof(uint32_t);
+
+        memcpy(data, ((uint8_t *)&metadata->tuning_params.data),
+                metadata->tuning_params.tuning_sensor_data_size);
+        data += metadata->tuning_params.tuning_sensor_data_size;
+
+        memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]),
+                metadata->tuning_params.tuning_vfe_data_size);
+        data += metadata->tuning_params.tuning_vfe_data_size;
+
+        memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]),
+                metadata->tuning_params.tuning_cpp_data_size);
+        data += metadata->tuning_params.tuning_cpp_data_size;
+
+
+        memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]),
+                metadata->tuning_params.tuning_cac_data_size);
+        data += metadata->tuning_params.tuning_cac_data_size;
+
+        camMetadata.update(QCAMERA3_TUNING_META_DATA_BLOB,
+            (int32_t*)tuning_meta_data_blob, (data-tuning_meta_data_blob)/sizeof(uint32_t));
+    }
     if (IS_META_AVAILABLE(CAM_INTF_META_NEUTRAL_COL_POINT, metadata)) {
         cam_neutral_col_point_t *neuColPoint = (cam_neutral_col_point_t*)
                 POINTER_OF_META(CAM_INTF_META_NEUTRAL_COL_POINT, metadata);
@@ -3040,6 +3199,7 @@
     for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
             it != mStreamInfo.end();) {
         if ((*it)->stream->format != HAL_PIXEL_FORMAT_RAW_OPAQUE &&
+                (*it)->stream->format != HAL_PIXEL_FORMAT_RAW10 &&
                 (*it)->stream->format != HAL_PIXEL_FORMAT_RAW16) {
             newStreamInfo.push_back(*it);
             it = mStreamInfo.erase(it);
@@ -3391,6 +3551,31 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : getMaxRawSize
+ *
+ * DESCRIPTION: Fetches maximum raw size supported by the cameraId
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : Largest supported Raw Dimension
+ *==========================================================================*/
+cam_dimension_t QCamera3HardwareInterface::getMaxRawSize(uint8_t camera_id)
+{
+    int max_width = 0;
+    cam_dimension_t maxRawSize;
+
+    memset(&maxRawSize, 0, sizeof(cam_dimension_t));
+    for (int i = 0; i < gCamCapability[camera_id]->supported_raw_dim_cnt; i++) {
+        if (max_width < gCamCapability[camera_id]->raw_dim[i].width) {
+            max_width = gCamCapability[camera_id]->raw_dim[i].width;
+            maxRawSize = gCamCapability[camera_id]->raw_dim[i];
+        }
+    }
+    return maxRawSize;
+}
+
+
+/*===========================================================================
  * FUNCTION   : calcMaxJpegDim
  *
  * DESCRIPTION: Calculates maximum jpeg dimension supported by the cameraId
@@ -3551,6 +3736,7 @@
             ANDROID_SCALER_AVAILABLE_FORMATS_RAW16,
             ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
             ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
+            HAL_PIXEL_FORMAT_RAW10,
             HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED};
     int scalar_formats_count = sizeof(scalar_formats)/sizeof(int32_t);
     staticInfo.update(ANDROID_SCALER_AVAILABLE_FORMATS,
@@ -3642,6 +3828,7 @@
         switch (scalar_formats[j]) {
         case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
         case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
+        case HAL_PIXEL_FORMAT_RAW10:
             for (int i = 0;
                 i < gCamCapability[cameraId]->supported_raw_dim_cnt; i++) {
                 available_stream_configs[idx] = scalar_formats[j];
@@ -3938,7 +4125,7 @@
             ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW };
     uint8_t available_capabilities_count =
             sizeof(available_capabilities)/sizeof(available_capabilities[0]);
-    if (!facingBack) {
+    if (CAM_SENSOR_YUV == gCamCapability[cameraId]->sensor_type.sens_type) {
         available_capabilities_count--;
     }
     staticInfo.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
@@ -4882,6 +5069,9 @@
 
     /* lens shading map mode */
     uint8_t shadingmap_mode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+    if (CAM_SENSOR_RAW == gCamCapability[mCameraId]->sensor_type.sens_type) {
+        shadingmap_mode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON;
+    }
     settings.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &shadingmap_mode, 1);
 
     //special defaults for manual template
@@ -5983,9 +6173,6 @@
     }
     delete hw;
 
-    pthread_mutex_lock(&mCameraSessionLock);
-    mCameraSessionActive = 0;
-    pthread_mutex_unlock(&mCameraSessionLock);
     CDBG("%s: X", __func__);
     return ret;
 }
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index 544efb6..fc1284d 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -193,6 +193,7 @@
     static cam_cds_mode_type_t lookupProp(const QCameraPropMap arr[],
             int len, const char *name);
     static int calcMaxJpegSize(uint8_t camera_id);
+    cam_dimension_t getMaxRawSize(uint8_t camera_id);
 
     int validateCaptureRequest(camera3_capture_request_t *request);
 
@@ -237,10 +238,12 @@
     QCamera3PicChannel *mPictureChannel;
     QCamera3RawChannel *mRawChannel;
     QCamera3SupportChannel *mSupportChannel;
+    QCamera3RawDumpChannel *mRawDumpChannel;
 
      //First request yet to be processed after configureStreams
     bool mFirstRequest;
     bool mFlush;
+    bool mEnableRawDump;
     QCamera3HeapMemory *mParamHeap;
     metadata_buffer_t* mParameters;
     bool m_bWNROn;
@@ -331,9 +334,6 @@
     static const QCameraMap TEST_PATTERN_MAP[];
     static const QCameraMap REFERENCE_ILLUMINANT_MAP[];
     static const QCameraPropMap CDS_MAP[];
-
-    static pthread_mutex_t mCameraSessionLock;
-    static unsigned int mCameraSessionActive;
 };
 
 }; // namespace qcamera
diff --git a/camera/QCamera2/HAL3/QCamera3VendorTags.cpp b/camera/QCamera2/HAL3/QCamera3VendorTags.cpp
index 78cf91a..d6a99a7 100644
--- a/camera/QCamera2/HAL3/QCamera3VendorTags.cpp
+++ b/camera/QCamera2/HAL3/QCamera3VendorTags.cpp
@@ -46,7 +46,8 @@
         QCAMERA3_PRIVATEDATA_END,
         QCAMERA3_CDS_END,
         QCAMERA3_OPAQUE_RAW_END,
-        QCAMERA3_CROP_END
+        QCAMERA3_CROP_END,
+        QCAMERA3_TUNING_META_DATA_END
 } ;
 
 typedef struct vendor_tag_info {
@@ -59,7 +60,8 @@
     "org.codeaurora.qcamera3.privatedata",
     "org.codeaurora.qcamera3.CDS",
     "org.codeaurora.qcamera3.opaque_raw",
-    "org.codeaurora.qcamera3.crop"
+    "org.codeaurora.qcamera3.crop",
+    "org.codeaurora.qcamera3.tuning_meta_data"
 };
 
 vendor_tag_info_t qcamera3_privatedata[QCAMERA3_PRIVATEDATA_END - QCAMERA3_PRIVATEDATA_START] = {
@@ -70,7 +72,8 @@
     { "cds", TYPE_INT32 }
 };
 
-vendor_tag_info_t qcamera3_opaque_raw[QCAMERA3_OPAQUE_RAW_END - QCAMERA3_OPAQUE_RAW_START] = {
+vendor_tag_info_t qcamera3_opaque_raw[QCAMERA3_OPAQUE_RAW_END -
+        QCAMERA3_OPAQUE_RAW_START] = {
     { "opaque_raw_strides", TYPE_INT32 },
     { "opaque_raw_format", TYPE_BYTE }
 };
@@ -81,12 +84,18 @@
     { "streamids", TYPE_INT32},
 };
 
+vendor_tag_info_t qcamera3_tuning_meta_data[QCAMERA3_TUNING_META_DATA_END -
+        QCAMERA3_TUNING_META_DATA_START] = {
+    { "tuning_meta_data_blob", TYPE_INT32 }
+};
+
 vendor_tag_info_t *qcamera3_tag_info[QCAMERA3_SECTIONS_END -
         VENDOR_SECTION] = {
     qcamera3_privatedata,
     qcamera3_cds,
     qcamera3_opaque_raw,
-    qcamera3_crop
+    qcamera3_crop,
+    qcamera3_tuning_meta_data
 };
 
 uint32_t qcamera3_all_tags[] = {
@@ -101,7 +110,10 @@
      // QCAMERA3_CROP
     (uint32_t)QCAMERA3_CROP_COUNT_REPROCESS,
     (uint32_t)QCAMERA3_CROP_REPROCESS,
-    (uint32_t)QCAMERA3_CROP_STREAM_ID_REPROCESS
+    (uint32_t)QCAMERA3_CROP_STREAM_ID_REPROCESS,
+
+    // QCAMERA3_TUNING_META_DATA
+    (uint32_t)QCAMERA3_TUNING_META_DATA_BLOB
 };
 
 const vendor_tag_ops_t* QCamera3VendorTags::Ops = NULL;
diff --git a/camera/QCamera2/HAL3/QCamera3VendorTags.h b/camera/QCamera2/HAL3/QCamera3VendorTags.h
index f69cbbf..fefc87b 100644
--- a/camera/QCamera2/HAL3/QCamera3VendorTags.h
+++ b/camera/QCamera2/HAL3/QCamera3VendorTags.h
@@ -37,6 +37,7 @@
     QCAMERA3_CDS,
     QCAMERA3_OPAQUE_RAW,
     QCAMERA3_CROP,
+    QCAMERA3_TUNING_META_DATA,
     QCAMERA3_SECTIONS_END
 };
 
@@ -44,7 +45,8 @@
     QCAMERA3_PRIVATEDATA_START = QCAMERA3_PRIVATEDATA << 16,
     QCAMERA3_CDS_START = QCAMERA3_CDS << 16,
     QCAMERA3_OPAQUE_RAW_START = QCAMERA3_OPAQUE_RAW << 16,
-    QCAMERA3_CROP_START = QCAMERA3_CROP << 16
+    QCAMERA3_CROP_START = QCAMERA3_CROP << 16,
+    QCAMERA3_TUNING_META_DATA_START = QCAMERA3_TUNING_META_DATA << 16,
 };
 
 enum qcamera3_ext_tags {
@@ -109,6 +111,9 @@
     QCAMERA3_CROP_REPROCESS,
     QCAMERA3_CROP_STREAM_ID_REPROCESS,
     QCAMERA3_CROP_END,
+
+    QCAMERA3_TUNING_META_DATA_BLOB = QCAMERA3_TUNING_META_DATA_START,
+    QCAMERA3_TUNING_META_DATA_END
 };
 
 // QCAMERA3_OPAQUE_RAW_FORMAT
diff --git a/camera/QCamera2/stack/common/cam_intf.h b/camera/QCamera2/stack/common/cam_intf.h
index b2869bd..f9f22d4 100644
--- a/camera/QCamera2/stack/common/cam_intf.h
+++ b/camera/QCamera2/stack/common/cam_intf.h
@@ -296,6 +296,9 @@
 
     uint8_t flash_available;
 
+    /* Sensor type information */
+    cam_sensor_type_t sensor_type;
+
     cam_rational_type_t base_gain_factor;    /* sensor base gain factor */
     /* AF Bracketing info */
     cam_af_bracketing_t  ubifocus_af_bracketing_need;
diff --git a/camera/QCamera2/stack/common/cam_types.h b/camera/QCamera2/stack/common/cam_types.h
index 46b96f1..4e7499b 100644
--- a/camera/QCamera2/stack/common/cam_types.h
+++ b/camera/QCamera2/stack/common/cam_types.h
@@ -953,6 +953,7 @@
     uint32_t tuning_vfe_data_size;
     uint32_t tuning_cpp_data_size;
     uint32_t tuning_cac_data_size;
+    uint32_t tuning_mod3_data_size;
     uint8_t  data[TUNING_DATA_MAX];
 }tuning_params_t;
 
@@ -1073,39 +1074,39 @@
     CAM_INTF_PARM_EV_STEP,
     CAM_INTF_PARM_AEC_LOCK,
     CAM_INTF_PARM_FPS_RANGE,
-    CAM_INTF_PARM_AWB_LOCK,
+    CAM_INTF_PARM_AWB_LOCK, /* 10 */
     CAM_INTF_PARM_EFFECT,
     CAM_INTF_PARM_BESTSHOT_MODE,
     CAM_INTF_PARM_DIS_ENABLE,
     CAM_INTF_PARM_LED_MODE,
-    CAM_INTF_META_HISTOGRAM, /* 10 */
+    CAM_INTF_META_HISTOGRAM,
     CAM_INTF_META_FACE_DETECTION,
 
     /* specific to HAl1 */
     CAM_INTF_META_AUTOFOCUS_DATA,
     CAM_INTF_PARM_QUERY_FLASH4SNAP,
     CAM_INTF_PARM_EXPOSURE,
-    CAM_INTF_PARM_SHARPNESS,
+    CAM_INTF_PARM_SHARPNESS, /* 20 */
     CAM_INTF_PARM_CONTRAST,
     CAM_INTF_PARM_SATURATION,
     CAM_INTF_PARM_BRIGHTNESS,
     CAM_INTF_PARM_ISO,
-    CAM_INTF_PARM_ZOOM, /* 20 */
+    CAM_INTF_PARM_ZOOM,
     CAM_INTF_PARM_ROLLOFF,
     CAM_INTF_PARM_MODE,             /* camera mode */
     CAM_INTF_PARM_AEC_ALGO_TYPE,    /* auto exposure algorithm */
     CAM_INTF_PARM_FOCUS_ALGO_TYPE,  /* focus algorithm */
-    CAM_INTF_PARM_AEC_ROI,
+    CAM_INTF_PARM_AEC_ROI, /* 30 */
     CAM_INTF_PARM_AF_ROI,
     CAM_INTF_PARM_SCE_FACTOR,
     CAM_INTF_PARM_FD,
-    CAM_INTF_PARM_MCE, /* 30 */
+    CAM_INTF_PARM_MCE,
     CAM_INTF_PARM_HFR,
     CAM_INTF_PARM_REDEYE_REDUCTION,
     CAM_INTF_PARM_WAVELET_DENOISE,
     CAM_INTF_PARM_TEMPORAL_DENOISE,
     CAM_INTF_PARM_HISTOGRAM,
-    CAM_INTF_PARM_ASD_ENABLE,
+    CAM_INTF_PARM_ASD_ENABLE, /* 40 */
     CAM_INTF_PARM_RECORDING_HINT,
     CAM_INTF_PARM_HDR,
     CAM_INTF_PARM_MAX_DIMENSION,
@@ -1115,7 +1116,7 @@
     CAM_INTF_PARM_BURST_NUM,
     CAM_INTF_PARM_RETRO_BURST_NUM,
     CAM_INTF_PARM_BURST_LED_ON_PERIOD,
-    CAM_INTF_PARM_HDR_NEED_1X, /* if HDR needs 1x output */ /* 40 */
+    CAM_INTF_PARM_HDR_NEED_1X, /* if HDR needs 1x output */ /* 50 */
     CAM_INTF_PARM_LOCK_CAF,
     CAM_INTF_PARM_VIDEO_HDR,
     CAM_INTF_PARM_SENSOR_HDR,
@@ -1125,7 +1126,7 @@
     CAM_INTF_META_CROP_DATA,
     CAM_INTF_META_PREP_SNAPSHOT_DONE,
     CAM_INTF_META_GOOD_FRAME_IDX_RANGE,
-    CAM_INTF_META_ASD_HDR_SCENE_DATA,
+    CAM_INTF_META_ASD_HDR_SCENE_DATA, /* 60 */
     CAM_INTF_META_ASD_SCENE_TYPE,
     CAM_INTF_META_CURRENT_SCENE,
     CAM_INTF_META_AEC_INFO,
@@ -1135,7 +1136,7 @@
     CAM_INTF_META_CHROMATIX_LITE_PP,
     CAM_INTF_META_CHROMATIX_LITE_AE,
     CAM_INTF_META_CHROMATIX_LITE_AWB,
-    CAM_INTF_META_CHROMATIX_LITE_AF,
+    CAM_INTF_META_CHROMATIX_LITE_AF, /* 70 */
     CAM_INTF_META_CHROMATIX_LITE_ASD,
     CAM_INTF_PARM_GET_CHROMATIX,
     CAM_INTF_PARM_SET_RELOAD_CHROMATIX,
@@ -1145,7 +1146,7 @@
     CAM_INTF_PARM_SET_VFE_COMMAND,
     CAM_INTF_PARM_SET_PP_COMMAND,
     CAM_INTF_PARM_TINTLESS,
-    CAM_INTF_PARM_LONGSHOT_ENABLE,
+    CAM_INTF_PARM_LONGSHOT_ENABLE, /* 80 */
     CAM_INTF_PARM_RDI_MODE,
     CAM_INTF_PARM_CDS_MODE,
 
@@ -1163,14 +1164,14 @@
     /* Whether the urgent metadata maps to a valid frame number */
     CAM_INTF_META_URGENT_FRAME_NUMBER_VALID,
     /* Whether the stream buffer corresponding this frame is dropped or not */
-    CAM_INTF_META_FRAME_DROPPED,
+    CAM_INTF_META_FRAME_DROPPED, /* 90 */
     /* Number of pending requests yet to be processed */
     CAM_INTF_META_PENDING_REQUESTS,
     /* COLOR CORRECTION.*/
     CAM_INTF_META_COLOR_CORRECT_MODE,
     /* A transform matrix to chromatically adapt pixels in the CIE XYZ (1931)
      * color space from the scene illuminant to the sRGB-standard D65-illuminant. */
-    CAM_INTF_META_COLOR_CORRECT_TRANSFORM, /* 50 */
+    CAM_INTF_META_COLOR_CORRECT_TRANSFORM,
     /*Color channel gains in the Bayer raw domain in the order [RGeGoB]*/
     CAM_INTF_META_COLOR_CORRECT_GAINS,
     /*The best fit color transform matrix calculated by the stats*/
@@ -1187,7 +1188,7 @@
     /*Number of streams and size of streams in current configuration*/
     CAM_INTF_META_STREAM_INFO,
     /* List of areas to use for metering */
-    CAM_INTF_META_AEC_ROI,
+    CAM_INTF_META_AEC_ROI, /* 100 */
     /* Whether the HAL must trigger precapture metering.*/
     CAM_INTF_META_AEC_PRECAPTURE_TRIGGER,
     /* The ID sent with the latest CAMERA2_TRIGGER_PRECAPTURE_METERING call */
@@ -1210,7 +1211,7 @@
     CAM_INTF_META_CAPTURE_INTENT,
     /* DEMOSAIC */
     /* Controls the quality of the demosaicing processing */
-    CAM_INTF_META_DEMOSAIC,
+    CAM_INTF_META_DEMOSAIC, /* 110 */
     /* EDGE */
     /* Operation mode for edge enhancement */
     CAM_INTF_META_EDGE_MODE,
@@ -1236,7 +1237,7 @@
     /* Size of the lens aperture */
     CAM_INTF_META_LENS_APERTURE,
     /* State of lens neutral density filter(s) */
-    CAM_INTF_META_LENS_FILTERDENSITY,
+    CAM_INTF_META_LENS_FILTERDENSITY, /* 120 */
     /* Lens optical zoom setting */
     CAM_INTF_META_LENS_FOCAL_LENGTH,
     /* Distance to plane of sharpest focus, measured from frontmost surface
@@ -1261,7 +1262,7 @@
      * pixel array */
     CAM_INTF_META_SCALER_CROP_REGION,
     /* The estimated scene illumination lighting frequency */
-    CAM_INTF_META_SCENE_FLICKER,
+    CAM_INTF_META_SCENE_FLICKER, /* 130 */
     /* SENSOR */
     /* Duration each pixel is exposed to light, in nanoseconds */
     CAM_INTF_META_SENSOR_EXPOSURE_TIME,
@@ -1288,7 +1289,7 @@
     /* Operating mode for histogram generation */
     CAM_INTF_META_STATS_HISTOGRAM_MODE,
     /* Operating mode for sharpness map generation */
-    CAM_INTF_META_STATS_SHARPNESS_MAP_MODE,
+    CAM_INTF_META_STATS_SHARPNESS_MAP_MODE, /* 140 */
     /* A 3-channel sharpness map, based on the raw sensor data,
      * If only a monochrome sharpness map is supported, all channels
      * should have the same data
@@ -1310,7 +1311,7 @@
     CAM_INTF_PARM_STATS_AF_PAAF,
     /* Indicates streams ID of all the requested buffers */
     CAM_INTF_META_STREAM_ID,
-    CAM_INTF_PARM_FOCUS_BRACKETING,
+    CAM_INTF_PARM_FOCUS_BRACKETING, /* 150 */
     CAM_INTF_PARM_FLASH_BRACKETING,
     CAM_INTF_PARM_GET_IMG_PROP,
     CAM_INTF_META_JPEG_GPS_COORDINATES,
@@ -1321,7 +1322,7 @@
     CAM_INTF_META_JPEG_THUMB_QUALITY,
     CAM_INTF_META_JPEG_THUMB_SIZE,
 
-    CAM_INTF_META_TEST_PATTERN_DATA,
+    CAM_INTF_META_TEST_PATTERN_DATA, /* 160 */
     /* DNG file support */
     CAM_INTF_META_PROFILE_TONE_CURVE,
     CAM_INTF_META_NEUTRAL_COL_POINT,
@@ -1597,6 +1598,16 @@
     CAM_FLASH_ON
 } cam_flash_value_t;
 
+typedef enum {
+    CAM_SENSOR_RAW,
+    CAM_SENSOR_YUV
+} cam_sensor_t;
+
+typedef struct {
+    cam_sensor_t sens_type;
+    cam_format_t native_format;
+} cam_sensor_type_t;
+
 typedef struct {
     /* reprocess feature mask */
     uint32_t feature_mask;
diff --git a/mixer_paths.xml b/mixer_paths.xml
index d21ffca..d42e3ef 100644
--- a/mixer_paths.xml
+++ b/mixer_paths.xml
@@ -722,6 +722,10 @@
 		<ctl name="COMP1 Switch" value="1" />
 	</path>
 
+	<path name="line">
+		<path name="headphones" />
+	</path>
+
 	<path name="headset-mic">
 		<path name="adc2" />
 		<ctl name="ADC1 Volume" value="0" />
@@ -756,6 +760,10 @@
 		<path name="headphones" />
 	</path>
 
+	<path name="voice-line">
+		<path name="headphones" />
+	</path>
+
 	<path name="voice-headset-mic">
 		<path name="headset-mic" />
 	</path>
diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml
index 1e3ea49..8ae5ea0 100644
--- a/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/overlay/frameworks/base/core/res/res/values/config.xml
@@ -106,7 +106,7 @@
     <bool name="config_cellBroadcastAppLinks">true</bool>
 
     <!-- Shutdown if the battery temperature exceeds (this value * 0.1) Celsius. -->
-    <integer name="config_shutdownBatteryTemperature">600</integer>
+    <integer name="config_shutdownBatteryTemperature">680</integer>
 
     <!-- Is the notification LED intrusive? Used to decide if there should be a disable option -->
     <bool name="config_intrusiveNotificationLed">true</bool>
@@ -247,8 +247,8 @@
     <!-- Vibrator pattern for feedback about touching a virtual key -->
     <integer-array name="config_virtualKeyVibePattern">
         <item>0</item>
+        <item>15</item>
         <item>10</item>
-        <item>8</item>
     </integer-array>
 
     <!-- Vibrator pattern for a very short but reliable vibration for soft keyboard tap -->
diff --git a/releasetools.py b/releasetools.py
index 4cc3c91..11470d4 100644
--- a/releasetools.py
+++ b/releasetools.py
@@ -219,7 +219,7 @@
   if d is None or len(d) > tf.size * common.OPTIONS.patch_threshold:
     # computing difference failed, or difference is nearly as
     # big as the target:  simply send the target.
-    WritePartitionImage(info, tf, "radio", "modem")
+    WritePartitionImage(info, tf, "radio")
   else:
     common.ZipWriteStr(info.output_zip, patchfile_name, d)
     info.script.Print("Patching modem image...")