Add support for platform-specific recording start time offset

o This start time offset is used in the media framework to eliminate
  the recording sound in the recorded file.

Change-Id: I97926a74f0743b8a4f985d51334e8d1486a318ea
related-to-bug: 4390777
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index f2107ec..ed26e63 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -150,6 +150,12 @@
      */
     Vector<int> getImageEncodingQualityLevels(int cameraId) const;
 
+    /**
+     * Returns the start time offset (in ms) for the given camera Id.
+     * If the given camera Id does not exist, -1 will be returned.
+     */
+    int getStartTimeOffsetMs(int cameraId) const;
+
 private:
     enum {
         // Camcorder profiles (high/low) and timelapse profiles (high/low)
@@ -332,6 +338,8 @@
 
     static int getCameraId(const char **atts);
 
+    void addStartTimeOffset(int cameraId, const char **atts);
+
     ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
     void addImageEncodingQualityLevel(int cameraId, const char** atts);
 
@@ -408,6 +416,7 @@
     Vector<VideoDecoderCap*>  mVideoDecoders;
     Vector<output_format>     mEncoderOutputFileFormats;
     Vector<ImageEncodingQualityLevels *>  mImageEncodingQualityLevels;
+    KeyedVector<int, int> mStartTimeOffsets;
 
     typedef struct {
         bool mHasRefProfile;      // Refers to an existing profile
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index e6f3a33..069bbb7 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -356,6 +356,18 @@
     return atoi(atts[1]);
 }
 
+void MediaProfiles::addStartTimeOffset(int cameraId, const char** atts)
+{
+    int offsetTimeMs = 700;
+    if (atts[2]) {
+        CHECK(!strcmp("startOffsetMs", atts[2]));
+        offsetTimeMs = atoi(atts[3]);
+    }
+
+    LOGV("%s: cameraId=%d, offset=%d ms", __func__, cameraId, offsetTimeMs);
+    mStartTimeOffsets.replaceValueFor(cameraId, offsetTimeMs);
+}
+
 /*static*/ void
 MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts)
 {
@@ -380,6 +392,7 @@
         profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts));
     } else if (strcmp("CamcorderProfiles", name) == 0) {
         profiles->mCurrentCameraId = getCameraId(atts);
+        profiles->addStartTimeOffset(profiles->mCurrentCameraId, atts);
     } else if (strcmp("EncoderProfile", name) == 0) {
         profiles->mCamcorderProfiles.add(
             createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds));
@@ -997,6 +1010,16 @@
     return result;
 }
 
+int MediaProfiles::getStartTimeOffsetMs(int cameraId) const {
+    int offsetTimeMs = -1;
+    ssize_t index = mStartTimeOffsets.indexOfKey(cameraId);
+    if (index >= 0) {
+        offsetTimeMs = mStartTimeOffsets.valueFor(cameraId);
+    }
+    LOGV("%s: offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId);
+    return offsetTimeMs;
+}
+
 MediaProfiles::~MediaProfiles()
 {
     CHECK("destructor should never be called" == 0);