Merge "Camera: Add vndk test for logical camera"
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 41d1833..01efb22 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -27,7 +27,6 @@
         "libmediadrmmetrics_lite",
         "libmediametrics",
         "libmediautils",
-        "libprotobuf-cpp-lite",
         "libstagefright_foundation",
         "libutils",
         "android.hardware.drm@1.0",
@@ -60,13 +59,11 @@
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
-        "libbase",
         "libbinder",
         "libhidlbase",
         "liblog",
         "libmediametrics",
         "libprotobuf-cpp-lite",
-        "libstagefright_foundation",
         "libutils",
     ],
     cflags: [
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 2909a50..253f400 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -80,7 +80,8 @@
                 Vector<SidxEntry> &sidx,
                 const Trex *trex,
                 off64_t firstMoofOffset,
-                const sp<ItemTable> &itemTable);
+                const sp<ItemTable> &itemTable,
+                int32_t elstShiftStartTicks);
     virtual status_t init();
 
     virtual media_status_t start();
@@ -109,7 +110,7 @@
     off64_t mFirstMoofOffset;
     off64_t mCurrentMoofOffset;
     off64_t mNextMoofOffset;
-    uint32_t mCurrentTime;
+    uint32_t mCurrentTime; // in media timescale ticks
     int32_t mLastParsedTrackId;
     int32_t mTrackId;
 
@@ -143,6 +144,10 @@
     bool mIsHeif;
     sp<ItemTable> mItemTable;
 
+    // Start offset from composition time to presentation time.
+    // Support shift only for video tracks through mElstShiftStartTicks for now.
+    int32_t mElstShiftStartTicks;
+
     size_t parseNALSize(const uint8_t *data) const;
     status_t parseChunk(off64_t *offset);
     status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
@@ -459,11 +464,12 @@
     [=] {
         int64_t duration;
         int32_t samplerate;
+        // Only for audio track.
         if (track->has_elst && mHeaderTimescale != 0 &&
                 AMediaFormat_getInt64(track->meta, AMEDIAFORMAT_KEY_DURATION, &duration) &&
                 AMediaFormat_getInt32(track->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &samplerate)) {
 
-            // elst has to be processed only the first time this function is called
+            // Elst has to be processed only the first time this function is called.
             track->has_elst = false;
 
             if (track->elst_segment_duration > INT64_MAX) {
@@ -479,67 +485,72 @@
                   halfscale, mHeaderTimescale, track->timescale);
 
             if ((uint32_t)samplerate != track->timescale){
-                ALOGV("samplerate:%" PRId32 ", track->timescale and samplerate are different!", samplerate);
+                ALOGV("samplerate:%" PRId32 ", track->timescale and samplerate are different!",
+                    samplerate);
             }
-
-            int64_t delay;
-            // delay = ((media_time * samplerate) + halfscale) / track->timescale;
-            if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
-                    __builtin_add_overflow(delay, halfscale, &delay) ||
-                    (delay /= track->timescale, false) ||
-                    delay > INT32_MAX ||
-                    delay < INT32_MIN) {
-                ALOGW("ignoring edit list with bogus values");
-                return;
+            // Both delay and paddingsamples have to be set inorder for either to be
+            // effective in the lower layers.
+            int64_t delay = 0;
+            if (media_time > 0) { // Gapless playback
+                // delay = ((media_time * samplerate) + halfscale) / track->timescale;
+                if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
+                        __builtin_add_overflow(delay, halfscale, &delay) ||
+                        (delay /= track->timescale, false) ||
+                        delay > INT32_MAX ||
+                        delay < INT32_MIN) {
+                    ALOGW("ignoring edit list with bogus values");
+                    return;
+                }
             }
             ALOGV("delay = %" PRId64, delay);
             AMediaFormat_setInt32(track->meta, AMEDIAFORMAT_KEY_ENCODER_DELAY, delay);
 
-            int64_t scaled_duration;
-            // scaled_duration = duration * mHeaderTimescale;
-            if (__builtin_mul_overflow(duration, mHeaderTimescale, &scaled_duration)) {
-                return;
-            }
-            ALOGV("scaled_duration = %" PRId64, scaled_duration);
-
-            int64_t segment_end;
-            int64_t padding;
-            int64_t segment_duration_e6;
-            int64_t media_time_scaled_e6;
-            int64_t media_time_scaled;
-            // padding = scaled_duration - ((segment_duration * 1000000) +
-            //                  ((media_time * mHeaderTimeScale * 1000000)/track->timescale) )
-            // segment_duration is based on timescale in movie header box(mdhd)
-            // media_time is based on timescale track header/media timescale
-            if (__builtin_mul_overflow(segment_duration, 1000000, &segment_duration_e6) ||
-                __builtin_mul_overflow(media_time, mHeaderTimescale, &media_time_scaled) ||
-                __builtin_mul_overflow(media_time_scaled, 1000000, &media_time_scaled_e6)) {
-                return;
-            }
-            media_time_scaled_e6 /= track->timescale;
-            if(__builtin_add_overflow(segment_duration_e6, media_time_scaled_e6, &segment_end) ||
-                __builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
-                return;
-            }
-            ALOGV("segment_end = %" PRId64 ", padding = %" PRId64, segment_end, padding);
             int64_t paddingsamples = 0;
-            if (padding < 0) {
+            if (segment_duration > 0) {
+                int64_t scaled_duration;
+                // scaled_duration = duration * mHeaderTimescale;
+                if (__builtin_mul_overflow(duration, mHeaderTimescale, &scaled_duration)) {
+                    return;
+                }
+                ALOGV("scaled_duration = %" PRId64, scaled_duration);
+
+                int64_t segment_end;
+                int64_t padding;
+                int64_t segment_duration_e6;
+                int64_t media_time_scaled_e6;
+                int64_t media_time_scaled;
+                // padding = scaled_duration - ((segment_duration * 1000000) +
+                //                  ((media_time * mHeaderTimescale * 1000000)/track->timescale) )
+                // segment_duration is based on timescale in movie header box(mdhd)
+                // media_time is based on timescale track header/media timescale
+                if (__builtin_mul_overflow(segment_duration, 1000000, &segment_duration_e6) ||
+                    __builtin_mul_overflow(media_time, mHeaderTimescale, &media_time_scaled) ||
+                    __builtin_mul_overflow(media_time_scaled, 1000000, &media_time_scaled_e6)) {
+                    return;
+                }
+                media_time_scaled_e6 /= track->timescale;
+                if (__builtin_add_overflow(segment_duration_e6, media_time_scaled_e6, &segment_end)
+                    || __builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
+                    return;
+                }
+                ALOGV("segment_end = %" PRId64 ", padding = %" PRId64, segment_end, padding);
                 // track duration from media header (which is what AMEDIAFORMAT_KEY_DURATION is)
                 // might be slightly shorter than the segment duration, which would make the
                 // padding negative. Clamp to zero.
-                padding = 0;
-            } else {
-                int64_t halfscale_e6;
-                int64_t timescale_e6;
-                // paddingsamples = ((padding * samplerate) + (halfscale * 1000000))
-                //                / (mHeaderTimescale * 1000000);
-                if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
-                        __builtin_mul_overflow(halfscale, 1000000, &halfscale_e6) ||
-                        __builtin_mul_overflow(mHeaderTimescale, 1000000, &timescale_e6) ||
-                        __builtin_add_overflow(paddingsamples, halfscale_e6, &paddingsamples) ||
-                        (paddingsamples /= timescale_e6, false) ||
-                        paddingsamples > INT32_MAX) {
-                    return;
+                if (padding > 0) {
+                    int64_t halfscale_mht = mHeaderTimescale / 2;
+                    int64_t halfscale_e6;
+                    int64_t timescale_e6;
+                    // paddingsamples = ((padding * samplerate) + (halfscale_mht * 1000000))
+                    //                / (mHeaderTimescale * 1000000);
+                    if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
+                            __builtin_mul_overflow(halfscale_mht, 1000000, &halfscale_e6) ||
+                            __builtin_mul_overflow(mHeaderTimescale, 1000000, &timescale_e6) ||
+                            __builtin_add_overflow(paddingsamples, halfscale_e6, &paddingsamples) ||
+                            (paddingsamples /= timescale_e6, false) ||
+                            paddingsamples > INT32_MAX) {
+                        return;
+                    }
                 }
             }
             ALOGV("paddingsamples = %" PRId64, paddingsamples);
@@ -668,6 +679,7 @@
             track->includes_expensive_metadata = false;
             track->skipTrack = false;
             track->timescale = 1000000;
+            track->elstShiftStartTicks = 0;
         }
     }
 
@@ -965,6 +977,7 @@
                         AMEDIAFORMAT_KEY_MIME, "application/octet-stream");
                 track->has_elst = false;
                 track->subsample_encryption = false;
+                track->elstShiftStartTicks = 0;
             }
 
             off64_t stop_offset = *offset + chunk_size;
@@ -1092,6 +1105,7 @@
 
             if (entry_count != 1) {
                 // we only support a single entry at the moment, for gapless playback
+                // or start offset
                 ALOGW("ignoring edit list with %d entries", entry_count);
             } else {
                 off64_t entriesoffset = data_offset + 8;
@@ -3929,9 +3943,15 @@
         }
     }
 
+    if (track->has_elst and !strncasecmp("video/", mime, 6) and track->elst_media_time > 0) {
+        track->elstShiftStartTicks = track->elst_media_time;
+        ALOGV("video track->elstShiftStartTicks :%" PRId64, track->elst_media_time);
+    }
+
     MPEG4Source *source =  new MPEG4Source(
             track->meta, mDataSource, track->timescale, track->sampleTable,
-            mSidxEntries, trex, mMoofOffset, itemTable);
+            mSidxEntries, trex, mMoofOffset, itemTable,
+            track->elstShiftStartTicks);
     if (source->init() != OK) {
         delete source;
         return NULL;
@@ -4332,7 +4352,8 @@
         Vector<SidxEntry> &sidx,
         const Trex *trex,
         off64_t firstMoofOffset,
-        const sp<ItemTable> &itemTable)
+        const sp<ItemTable> &itemTable,
+        int32_t elstShiftStartTicks)
     : mFormat(format),
       mDataSource(dataSource),
       mTimescale(timeScale),
@@ -4360,7 +4381,8 @@
       mBuffer(NULL),
       mSrcBuffer(NULL),
       mIsHeif(itemTable != NULL),
-      mItemTable(itemTable) {
+      mItemTable(itemTable),
+      mElstShiftStartTicks(elstShiftStartTicks) {
 
     memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
 
@@ -4445,11 +4467,31 @@
 }
 
 status_t MPEG4Source::init() {
+    status_t err = OK;
+    const char *mime;
+    CHECK(AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime));
     if (mFirstMoofOffset != 0) {
         off64_t offset = mFirstMoofOffset;
-        return parseChunk(&offset);
+        err = parseChunk(&offset);
+        if(err == OK && !strncasecmp("video/", mime, 6)
+            && !mCurrentSamples.isEmpty()) {
+            // Start offset should be less or equal to composition time of first sample.
+            // ISO : sample_composition_time_offset, version 0 (unsigned) for major brands.
+            mElstShiftStartTicks = std::min(mElstShiftStartTicks,
+                (*mCurrentSamples.begin()).compositionOffset);
+        }
+        return err;
     }
-    return OK;
+
+    if (!strncasecmp("video/", mime, 6)) {
+        uint32_t firstSampleCTS = 0;
+        err = mSampleTable->getMetaDataForSample(0, NULL, NULL, &firstSampleCTS);
+        // Start offset should be less or equal to composition time of first sample.
+        // Composition time stamp of first sample cannot be negative.
+        mElstShiftStartTicks = std::min(mElstShiftStartTicks, (int32_t)firstSampleCTS);
+    }
+
+    return err;
 }
 
 MPEG4Source::~MPEG4Source() {
@@ -4990,7 +5032,7 @@
 
 status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
 
-    ALOGV("MPEG4Extractor::parseTrackFragmentRun");
+    ALOGV("MPEG4Source::parseTrackFragmentRun");
     if (size < 8) {
         return -EINVAL;
     }
@@ -5132,10 +5174,10 @@
         }
 
         ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, "
-              " flags 0x%08x", i + 1,
+              " flags 0x%08x ctsOffset %" PRIu32, i + 1,
                 dataOffset, sampleSize, sampleDuration,
                 (flags & kFirstSampleFlagsPresent) && i == 0
-                    ? firstSampleFlags : sampleFlags);
+                    ? firstSampleFlags : sampleFlags, sampleCtsOffset);
         tmp.offset = dataOffset;
         tmp.size = sampleSize;
         tmp.duration = sampleDuration;
@@ -5227,6 +5269,7 @@
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+
         if (mIsHeif) {
             CHECK(mSampleTable == NULL);
             CHECK(mItemTable != NULL);
@@ -5264,6 +5307,9 @@
                     CHECK(!"Should not be here.");
                     break;
             }
+            if( mode != ReadOptions::SEEK_FRAME_INDEX) {
+                seekTimeUs += ((int64_t)mElstShiftStartTicks * 1000000) / mTimescale;
+            }
 
             uint32_t sampleIndex;
             status_t err = mSampleTable->findSampleAtTime(
@@ -5305,6 +5351,7 @@
 
             if (mode == ReadOptions::SEEK_CLOSEST
                 || mode == ReadOptions::SEEK_FRAME_INDEX) {
+                sampleTime -= mElstShiftStartTicks;
                 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
             }
 
@@ -5343,6 +5390,10 @@
         if (!mIsHeif) {
             err = mSampleTable->getMetaDataForSample(
                     mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
+            if(err == OK) {
+                cts -= mElstShiftStartTicks;
+            }
+
         } else {
             err = mItemTable->getImageOffsetAndSize(
                     options && options->getSeekTo(&seekTimeUs, &mode) ?
@@ -5623,6 +5674,10 @@
     ReadOptions::SeekMode mode;
     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
 
+        seekTimeUs += ((int64_t)mElstShiftStartTicks * 1000000) / mTimescale;
+        ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRId32, seekTimeUs,
+                mElstShiftStartTicks);
+
         int numSidxEntries = mSegments.size();
         if (numSidxEntries != 0) {
             int64_t totalTime = 0;
@@ -5709,6 +5764,8 @@
         offset = smpl->offset;
         size = smpl->size;
         cts = mCurrentTime + smpl->compositionOffset;
+        cts -= mElstShiftStartTicks;
+
         mCurrentTime += smpl->duration;
         isSyncSample = (mCurrentSampleIndex == 0);
 
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index 79d5ff6dd..fadfb50 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -85,6 +85,7 @@
         bool has_elst;
         int64_t elst_media_time;
         uint64_t elst_segment_duration;
+        int32_t elstShiftStartTicks;
         bool subsample_encryption;
     };
 
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index 2567b3b..86711de 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -302,14 +302,19 @@
     if (audio_channel_mask_get_representation(channelMask)
                 == AUDIO_CHANNEL_REPRESENTATION_POSITION
             && DownmixerBufferProvider::isMultichannelCapable()) {
-        mDownmixerBufferProvider.reset(new DownmixerBufferProvider(channelMask,
-                mMixerChannelMask,
-                AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
-                sampleRate, sessionId, kCopyBufferFrameCount));
-        if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())->isValid()) {
-            mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
-            reconfigureBufferProviders();
-            return NO_ERROR;
+
+        // Check if we have a float or int16 downmixer, in that order.
+        for (const audio_format_t format : { AUDIO_FORMAT_PCM_FLOAT, AUDIO_FORMAT_PCM_16_BIT }) {
+            mDownmixerBufferProvider.reset(new DownmixerBufferProvider(
+                    channelMask, mMixerChannelMask,
+                    format,
+                    sampleRate, sessionId, kCopyBufferFrameCount));
+            if (static_cast<DownmixerBufferProvider *>(mDownmixerBufferProvider.get())
+                    ->isValid()) {
+                mDownmixRequiresFormat = format;
+                reconfigureBufferProviders();
+                return NO_ERROR;
+            }
         }
         // mDownmixerBufferProvider reset below.
     }
diff --git a/media/libeffects/downmix/Android.bp b/media/libeffects/downmix/Android.bp
index 227f2a1..9c82b1d 100644
--- a/media/libeffects/downmix/Android.bp
+++ b/media/libeffects/downmix/Android.bp
@@ -13,7 +13,7 @@
     relative_install_path: "soundfx",
 
     cflags: [
-        //"-DBUILD_FLOAT",
+        "-DBUILD_FLOAT",
         "-fvisibility=hidden",
         "-Wall",
         "-Werror",
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index b4a1d77..99ac4f5 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -31,10 +31,12 @@
 // Do not submit with DOWNMIX_ALWAYS_USE_GENERIC_DOWNMIXER defined, strictly for testing
 //#define DOWNMIX_ALWAYS_USE_GENERIC_DOWNMIXER 0
 
-#define MINUS_3_DB_IN_Q19_12 2896 // -3dB = 0.707 * 2^12 = 2896
-
 #ifdef BUILD_FLOAT
 #define MINUS_3_DB_IN_FLOAT 0.70710678f // -3dB = 0.70710678f
+const audio_format_t gTargetFormat = AUDIO_FORMAT_PCM_FLOAT;
+#else
+#define MINUS_3_DB_IN_Q19_12 2896 // -3dB = 0.707 * 2^12 = 2896
+const audio_format_t gTargetFormat = AUDIO_FORMAT_PCM_16_BIT;
 #endif
 
 // subset of possible audio_channel_mask_t values, and AUDIO_CHANNEL_OUT_* renamed to CHANNEL_MASK_*
@@ -703,7 +705,7 @@
     memset(&pDwmModule->context, 0, sizeof(downmix_object_t));
 
     pDwmModule->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
-    pDwmModule->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pDwmModule->config.inputCfg.format = gTargetFormat;
     pDwmModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_7POINT1;
     pDwmModule->config.inputCfg.bufferProvider.getBuffer = NULL;
     pDwmModule->config.inputCfg.bufferProvider.releaseBuffer = NULL;
@@ -715,7 +717,7 @@
 
     // set a default value for the access mode, but should be overwritten by caller
     pDwmModule->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
-    pDwmModule->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pDwmModule->config.outputCfg.format = gTargetFormat;
     pDwmModule->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
     pDwmModule->config.outputCfg.bufferProvider.getBuffer = NULL;
     pDwmModule->config.outputCfg.bufferProvider.releaseBuffer = NULL;
@@ -762,8 +764,8 @@
     // Check configuration compatibility with build options, and effect capabilities
     if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate
         || pConfig->outputCfg.channels != DOWNMIX_OUTPUT_CHANNELS
-        || pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT
-        || pConfig->outputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+        || pConfig->inputCfg.format != gTargetFormat
+        || pConfig->outputCfg.format != gTargetFormat) {
         ALOGE("Downmix_Configure error: invalid config");
         return -EINVAL;
     }
@@ -1185,8 +1187,8 @@
     if (accumulate) {
         while (numFrames) {
             // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
-            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12)
-                    + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_FLOAT)
+                    + (pSrc[3] * MINUS_3_DB_IN_FLOAT);
             // FL + centerPlusLfeContrib + SL + RL
             lt = pSrc[0] + centerPlusLfeContrib + pSrc[6] + pSrc[4];
             // FR + centerPlusLfeContrib + SR + RR
@@ -1427,4 +1429,4 @@
     }
     return true;
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libmedia/NdkWrapper.cpp b/media/libmedia/NdkWrapper.cpp
index eed96e7..156991e 100644
--- a/media/libmedia/NdkWrapper.cpp
+++ b/media/libmedia/NdkWrapper.cpp
@@ -57,6 +57,10 @@
     AMEDIAFORMAT_KEY_COLOR_STANDARD,
     AMEDIAFORMAT_KEY_COLOR_TRANSFER,
     AMEDIAFORMAT_KEY_COMPLEXITY,
+    AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
+    AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
+    AMEDIAFORMAT_KEY_CRYPTO_MODE,
+    AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK,
     AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
     AMEDIAFORMAT_KEY_GRID_COLUMNS,
     AMEDIAFORMAT_KEY_GRID_ROWS,
@@ -102,6 +106,8 @@
 };
 
 static const char *AMediaFormatKeyGroupBuffer[] = {
+    AMEDIAFORMAT_KEY_CRYPTO_IV,
+    AMEDIAFORMAT_KEY_CRYPTO_KEY,
     AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
     AMEDIAFORMAT_KEY_SEI,
     AMEDIAFORMAT_KEY_MPEG_USER_DATA,
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 6b43375..54309ee 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -91,18 +91,15 @@
         "JMedia2HTTPConnection.cpp",
     ],
 
+    header_libs: [
+        "libbinder_headers",
+        "libnativehelper_header_only",
+    ],
+
     shared_libs: [
-        "android.hidl.token@1.0-utils",
         "liblog",
-        "libcutils",
         "libutils",
-        "libbinder",
-        "libstagefright_foundation",
-        "libmediaextractor",
         "libdl",
-        "libaudioutils",
-        "libaudioclient",
-        "libnativehelper",
     ],
 
     include_dirs: [
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
index f01361b..9552580 100644
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
@@ -1286,6 +1286,11 @@
             mVideoTimeUs = timeUs;
         }
 
+        sp<AMediaCodecCryptoInfoWrapper> cryptInfo = extractor->getSampleCryptoInfo();
+        if (cryptInfo != NULL) {
+            meta->setObject("cryptInfo", cryptInfo);
+        }
+
         queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
 
         if (numBuffers == 0 && actualTimeUs != nullptr) {
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
index 49e3e3b..a5bd62d 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
@@ -1108,6 +1108,11 @@
             } // buffer->data()
         } // needsCopy
 
+        sp<RefBase> cryptInfoObj;
+        if (buffer->meta()->findObject("cryptInfo", &cryptInfoObj)) {
+            cryptInfo = static_cast<AMediaCodecCryptoInfoWrapper *>(cryptInfoObj.get());
+        }
+
         status_t err;
         if (cryptInfo != NULL) {
             err = mCodec->queueSecureInputBuffer(
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 6ad0417..60b236d 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -4421,8 +4421,8 @@
         h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1);
 
         // disable B-frames until MPEG4Writer can guarantee finalizing files with B-frames
-        h264type.nRefFrames = 1;
-        h264type.nBFrames = 0;
+        // h264type.nRefFrames = 1;
+        // h264type.nBFrames = 0;
 
         h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
         h264type.nAllowedPictureTypes =
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 3ad82d9..2a819ad 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -19,6 +19,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "CameraSourceTimeLapse"
 
+#include <media/hardware/HardwareAPI.h>
 #include <binder/IPCThreadState.h>
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
@@ -172,8 +173,16 @@
     ALOGV("signalBufferReturned");
     Mutex::Autolock autoLock(mQuickStopLock);
     if (mQuickStop && (buffer == mLastReadBufferCopy)) {
+        if (metaDataStoredInVideoBuffers() == kMetadataBufferTypeNativeHandleSource) {
+            native_handle_t* handle = (
+                (VideoNativeHandleMetadata*)(mLastReadBufferCopy->data()))->pHandle;
+            native_handle_close(handle);
+            native_handle_delete(handle);
+        }
         buffer->setObserver(NULL);
         buffer->release();
+        mLastReadBufferCopy = NULL;
+        mForceRead = true;
     } else {
         return CameraSource::signalBufferReturned(buffer);
     }
@@ -182,7 +191,8 @@
 void createMediaBufferCopy(
         const MediaBufferBase& sourceBuffer,
         int64_t frameTime,
-        MediaBufferBase **newBuffer) {
+        MediaBufferBase **newBuffer,
+        int32_t videoBufferMode) {
 
     ALOGV("createMediaBufferCopy");
     size_t sourceSize = sourceBuffer.size();
@@ -192,13 +202,20 @@
     memcpy((*newBuffer)->data(), sourcePointer, sourceSize);
 
     (*newBuffer)->meta_data().setInt64(kKeyTime, frameTime);
+
+    if (videoBufferMode == kMetadataBufferTypeNativeHandleSource) {
+        ((VideoNativeHandleMetadata*)((*newBuffer)->data()))->pHandle =
+            native_handle_clone(
+                ((VideoNativeHandleMetadata*)(sourceBuffer.data()))->pHandle);
+    }
 }
 
 void CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBufferBase& sourceBuffer) {
     ALOGV("fillLastReadBufferCopy");
     int64_t frameTime;
     CHECK(sourceBuffer.meta_data().findInt64(kKeyTime, &frameTime));
-    createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy);
+    createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy,
+        metaDataStoredInVideoBuffers());
     mLastReadBufferCopy->add_ref();
     mLastReadBufferCopy->setObserver(this);
 }
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index a48466a..b45eb03 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -137,6 +137,8 @@
 
 private:
     enum {
+        // TODO: need to increase this considering the bug
+        // about camera app not sending video frames continuously?
         kMaxCttsOffsetTimeUs = 1000000LL,  // 1 second
         kSampleArraySize = 1000,
     };
@@ -317,6 +319,7 @@
     ListTableEntries<uint32_t, 1> *mStssTableEntries;
     ListTableEntries<uint32_t, 2> *mSttsTableEntries;
     ListTableEntries<uint32_t, 2> *mCttsTableEntries;
+    ListTableEntries<uint32_t, 3> *mElstTableEntries; // 3columns: segDuration, mediaTime, mediaRate
 
     int64_t mMinCttsOffsetTimeUs;
     int64_t mMinCttsOffsetTicks;
@@ -416,6 +419,8 @@
     // Duration is time scale based
     void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur);
     void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur);
+    void addOneElstTableEntry(uint32_t segmentDuration, int32_t mediaTime,
+        int16_t mediaRate, int16_t mediaRateFraction);
 
     bool isTrackMalFormed() const;
     void sendTrackSummary(bool hasMultipleTracks);
@@ -448,6 +453,7 @@
     void writeVideoFourCCBox();
     void writeMetadataFourCCBox();
     void writeStblBox(bool use32BitOffset);
+    void writeEdtsBox();
 
     Track(const Track &);
     Track &operator=(const Track &);
@@ -483,6 +489,7 @@
 
     mStartTimestampUs = -1ll;
     mStartTimeOffsetMs = -1;
+    mStartTimeOffsetBFramesUs = 0;
     mPaused = false;
     mStarted = false;
     mWriterThreadStarted = false;
@@ -1272,6 +1279,10 @@
     // Adjust the global start time.
     mStartTimestampUs += minCttsOffsetTimeUs - kMaxCttsOffsetTimeUs;
 
+    // Add mStartTimeOffsetBFramesUs(-ve or zero) to the duration of first entry in STTS.
+    mStartTimeOffsetBFramesUs = minCttsOffsetTimeUs - kMaxCttsOffsetTimeUs;
+    ALOGV("mStartTimeOffsetBFramesUs :%" PRId32, mStartTimeOffsetBFramesUs);
+
     for (List<Track *>::iterator it = mTracks.begin();
         it != mTracks.end(); ++it) {
         if (!(*it)->isHeic()) {
@@ -1747,6 +1758,11 @@
     return mStartTimestampUs;
 }
 
+int32_t MPEG4Writer::getStartTimeOffsetBFramesUs() {
+    Mutex::Autolock autoLock(mLock);
+    return mStartTimeOffsetBFramesUs;
+}
+
 size_t MPEG4Writer::numTracks() {
     Mutex::Autolock autolock(mLock);
     return mTracks.size();
@@ -1776,6 +1792,7 @@
       mStssTableEntries(new ListTableEntries<uint32_t, 1>(1000)),
       mSttsTableEntries(new ListTableEntries<uint32_t, 2>(1000)),
       mCttsTableEntries(new ListTableEntries<uint32_t, 2>(1000)),
+      mElstTableEntries(new ListTableEntries<uint32_t, 3>(3)), // Reserve 3 rows, a row has 3 items
       mMinCttsOffsetTimeUs(0),
       mMinCttsOffsetTicks(0),
       mMaxCttsOffsetTicks(0),
@@ -1842,46 +1859,48 @@
 
 // Clear all the internal states except the CSD data.
 void MPEG4Writer::Track::resetInternal() {
-      mDone = false;
-      mPaused = false;
-      mResumed = false;
-      mStarted = false;
-      mGotStartKeyFrame = false;
-      mIsMalformed = false;
-      mTrackDurationUs = 0;
-      mEstimatedTrackSizeBytes = 0;
-      mSamplesHaveSameSize = 0;
-      if (mStszTableEntries != NULL) {
-         delete mStszTableEntries;
-         mStszTableEntries = new ListTableEntries<uint32_t, 1>(1000);
-      }
-
-      if (mStcoTableEntries != NULL) {
-         delete mStcoTableEntries;
-         mStcoTableEntries = new ListTableEntries<uint32_t, 1>(1000);
-      }
-      if (mCo64TableEntries != NULL) {
-         delete mCo64TableEntries;
-         mCo64TableEntries = new ListTableEntries<off64_t, 1>(1000);
-      }
-
-      if (mStscTableEntries != NULL) {
-         delete mStscTableEntries;
-         mStscTableEntries = new ListTableEntries<uint32_t, 3>(1000);
-      }
-      if (mStssTableEntries != NULL) {
-         delete mStssTableEntries;
-         mStssTableEntries = new ListTableEntries<uint32_t, 1>(1000);
-      }
-      if (mSttsTableEntries != NULL) {
-         delete mSttsTableEntries;
-         mSttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
-      }
-      if (mCttsTableEntries != NULL) {
-         delete mCttsTableEntries;
-         mCttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
-      }
-      mReachedEOS = false;
+    mDone = false;
+    mPaused = false;
+    mResumed = false;
+    mStarted = false;
+    mGotStartKeyFrame = false;
+    mIsMalformed = false;
+    mTrackDurationUs = 0;
+    mEstimatedTrackSizeBytes = 0;
+    mSamplesHaveSameSize = 0;
+    if (mStszTableEntries != NULL) {
+        delete mStszTableEntries;
+        mStszTableEntries = new ListTableEntries<uint32_t, 1>(1000);
+    }
+    if (mStcoTableEntries != NULL) {
+        delete mStcoTableEntries;
+        mStcoTableEntries = new ListTableEntries<uint32_t, 1>(1000);
+    }
+    if (mCo64TableEntries != NULL) {
+        delete mCo64TableEntries;
+        mCo64TableEntries = new ListTableEntries<off64_t, 1>(1000);
+    }
+    if (mStscTableEntries != NULL) {
+        delete mStscTableEntries;
+        mStscTableEntries = new ListTableEntries<uint32_t, 3>(1000);
+    }
+    if (mStssTableEntries != NULL) {
+        delete mStssTableEntries;
+        mStssTableEntries = new ListTableEntries<uint32_t, 1>(1000);
+    }
+    if (mSttsTableEntries != NULL) {
+        delete mSttsTableEntries;
+        mSttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
+    }
+    if (mCttsTableEntries != NULL) {
+        delete mCttsTableEntries;
+        mCttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
+    }
+    if (mElstTableEntries != NULL) {
+        delete mElstTableEntries;
+        mElstTableEntries = new ListTableEntries<uint32_t, 3>(3);
+    }
+    mReachedEOS = false;
 }
 
 void MPEG4Writer::Track::updateTrackSizeEstimate() {
@@ -1900,6 +1919,7 @@
                                     mStssTableEntries->count() * 4 +   // stss box size
                                     mSttsTableEntries->count() * 8 +   // stts box size
                                     mCttsTableEntries->count() * 8 +   // ctts box size
+                                    mElstTableEntries->count() * 12 +   // elst box size
                                     stcoBoxSizeBytes +           // stco box size
                                     stszBoxSizeBytes;            // stsz box size
     }
@@ -1936,6 +1956,16 @@
     mCttsTableEntries->add(htonl(duration));
 }
 
+void MPEG4Writer::Track::addOneElstTableEntry(
+    uint32_t segmentDuration, int32_t mediaTime, int16_t mediaRate, int16_t mediaRateFraction) {
+    ALOGV("segmentDuration:%u, mediaTime:%d", segmentDuration, mediaTime);
+    ALOGV("mediaRate :%" PRId16 ", mediaRateFraction :%" PRId16 ", Ored %u", mediaRate,
+        mediaRateFraction, ((((uint32_t)mediaRate) << 16) | ((uint32_t)mediaRateFraction)));
+    mElstTableEntries->add(htonl(segmentDuration));
+    mElstTableEntries->add(htonl(mediaTime));
+    mElstTableEntries->add(htonl((((uint32_t)mediaRate) << 16) | (uint32_t)mediaRateFraction));
+}
+
 status_t MPEG4Writer::setNextFd(int fd) {
     ALOGV("addNextFd");
     Mutex::Autolock l(mLock);
@@ -2173,6 +2203,7 @@
     delete mSttsTableEntries;
     delete mStssTableEntries;
     delete mCttsTableEntries;
+    delete mElstTableEntries;
 
     mStszTableEntries = NULL;
     mStcoTableEntries = NULL;
@@ -2181,6 +2212,7 @@
     mSttsTableEntries = NULL;
     mStssTableEntries = NULL;
     mCttsTableEntries = NULL;
+    mElstTableEntries = NULL;
 
     if (mCodecSpecificData != NULL) {
         free(mCodecSpecificData);
@@ -3612,6 +3644,7 @@
     uint32_t now = getMpeg4Time();
     mOwner->beginBox("trak");
         writeTkhdBox(now);
+        writeEdtsBox();
         mOwner->beginBox("mdia");
             writeMdhdBox(now);
             writeHdlrBox();
@@ -3982,6 +4015,33 @@
     mOwner->endBox();
 }
 
+void MPEG4Writer::Track::writeEdtsBox(){
+    ALOGV("%s : getStartTimeOffsetTimeUs of track:%" PRId64 " us", getTrackType(),
+        getStartTimeOffsetTimeUs());
+
+    // Prepone video playback.
+    if (mMinCttsOffsetTicks != mMaxCttsOffsetTicks) {
+        int32_t mvhdTimeScale = mOwner->getTimeScale();
+        uint32_t tkhdDuration = (mTrackDurationUs * mvhdTimeScale + 5E5) / 1E6;
+        int64_t mediaTime = ((kMaxCttsOffsetTimeUs - getMinCttsOffsetTimeUs())
+            * mTimeScale + 5E5) / 1E6;
+        if (tkhdDuration > 0 && mediaTime > 0) {
+            addOneElstTableEntry(tkhdDuration, mediaTime, 1, 0);
+        }
+    }
+
+    if (mElstTableEntries->count() == 0) {
+        return;
+    }
+
+    mOwner->beginBox("edts");
+        mOwner->beginBox("elst");
+            mOwner->writeInt32(0); // version=0, flags=0
+            mElstTableEntries->write(mOwner);
+        mOwner->endBox(); // elst;
+    mOwner->endBox(); // edts
+}
+
 void MPEG4Writer::Track::writeMdhdBox(uint32_t now) {
     int64_t trakDurationUs = getDurationUs();
     int64_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6;
@@ -4118,7 +4178,9 @@
         uint32_t duration;
         CHECK(mSttsTableEntries->get(duration, 1));
         duration = htonl(duration);  // Back to host byte order
-        mSttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime()), 1);
+        int32_t startTimeOffsetScaled = (((getStartTimeOffsetTimeUs() +
+            mOwner->getStartTimeOffsetBFramesUs()) * mTimeScale) + 500000LL) / 1000000LL;
+        mSttsTableEntries->set(htonl((int32_t)duration + startTimeOffsetScaled), 1);
     }
     mSttsTableEntries->write(mOwner);
     mOwner->endBox();  // stts
diff --git a/media/libstagefright/codecs/flac/dec/Android.bp b/media/libstagefright/codecs/flac/dec/Android.bp
index 1674cb2..3d4a44f 100644
--- a/media/libstagefright/codecs/flac/dec/Android.bp
+++ b/media/libstagefright/codecs/flac/dec/Android.bp
@@ -29,7 +29,6 @@
     },
 
     shared_libs: [
-        "libcutils",
         "liblog",
         "libstagefright_flacdec",
         "libstagefright_omx",
diff --git a/media/libstagefright/include/media/stagefright/MPEG4Writer.h b/media/libstagefright/include/media/stagefright/MPEG4Writer.h
index f18940d..1abef8c 100644
--- a/media/libstagefright/include/media/stagefright/MPEG4Writer.h
+++ b/media/libstagefright/include/media/stagefright/MPEG4Writer.h
@@ -110,6 +110,7 @@
     uint32_t mInterleaveDurationUs;
     int32_t mTimeScale;
     int64_t mStartTimestampUs;
+    int32_t mStartTimeOffsetBFramesUs; // Start time offset when B Frames are present
     int mLatitudex10000;
     int mLongitudex10000;
     bool mAreGeoTagsAvailable;
@@ -129,6 +130,7 @@
 
     void setStartTimestampUs(int64_t timeUs);
     int64_t getStartTimestampUs();  // Not const
+    int32_t getStartTimeOffsetBFramesUs();
     status_t startTracks(MetaData *params);
     size_t numTracks();
     int64_t estimateMoovBoxSize(int32_t bitRate);
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaController.java b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
index 8c3a013..c060aaf 100644
--- a/packages/MediaComponents/apex/java/android/media/session/MediaController.java
+++ b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
@@ -153,9 +153,7 @@
             return false;
         }
         try {
-            //TODO(b/119748678): Resolve mContext.getOpPackageName() through this file.
-            // Temporarilly it's replaced with "mContext.getOpPackageName()" for compiling.
-            return mSessionBinder.sendMediaButton("mContext.getOpPackageName()", mCbStub,
+            return mSessionBinder.sendMediaButton(mContext.getOpPackageName(), mCbStub,
                     asSystemService, keyEvent);
         } catch (RemoteException e) {
             // System is dead. =(
@@ -188,7 +186,7 @@
                         break;
                 }
                 try {
-                    mSessionBinder.adjustVolume("mContext.getOpPackageName()", mCbStub, true,
+                    mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, true,
                             direction, AudioManager.FLAG_SHOW_UI);
                 } catch (RemoteException e) {
                     Log.wtf(TAG, "Error calling adjustVolumeBy", e);
@@ -199,7 +197,7 @@
                 final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE
                         | AudioManager.FLAG_FROM_KEY;
                 try {
-                    mSessionBinder.adjustVolume("mContext.getOpPackageName()", mCbStub, true, 0,
+                    mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, true, 0,
                             flags);
                 } catch (RemoteException e) {
                     Log.wtf(TAG, "Error calling adjustVolumeBy", e);
@@ -369,7 +367,7 @@
      */
     public void setVolumeTo(int value, int flags) {
         try {
-            mSessionBinder.setVolumeTo("mContext.getOpPackageName()", mCbStub, value, flags);
+            mSessionBinder.setVolumeTo(mContext.getOpPackageName(), mCbStub, value, flags);
         } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling setVolumeTo.", e);
         }
@@ -390,7 +388,7 @@
      */
     public void adjustVolume(int direction, int flags) {
         try {
-            mSessionBinder.adjustVolume("mContext.getOpPackageName()", mCbStub, false, direction,
+            mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, false, direction,
                     flags);
         } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
@@ -457,7 +455,7 @@
             throw new IllegalArgumentException("command cannot be null or empty");
         }
         try {
-            mSessionBinder.sendCommand("mContext.getOpPackageName()", mCbStub, command, args, cb);
+            mSessionBinder.sendCommand(mContext.getOpPackageName(), mCbStub, command, args, cb);
         } catch (RemoteException e) {
             Log.d(TAG, "Dead object in sendCommand.", e);
         }
@@ -523,7 +521,7 @@
 
         if (!mCbRegistered) {
             try {
-                mSessionBinder.registerCallbackListener("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.registerCallbackListener(mContext.getOpPackageName(), mCbStub);
                 mCbRegistered = true;
             } catch (RemoteException e) {
                 Log.e(TAG, "Dead object in registerCallback", e);
@@ -670,7 +668,7 @@
          */
         public void prepare() {
             try {
-                mSessionBinder.prepare("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.prepare(mContext.getOpPackageName(), mCbStub);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling prepare.", e);
             }
@@ -694,7 +692,7 @@
                         "You must specify a non-empty String for prepareFromMediaId.");
             }
             try {
-                mSessionBinder.prepareFromMediaId("mContext.getOpPackageName()", mCbStub, mediaId,
+                mSessionBinder.prepareFromMediaId(mContext.getOpPackageName(), mCbStub, mediaId,
                         extras);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
@@ -721,7 +719,7 @@
                 query = "";
             }
             try {
-                mSessionBinder.prepareFromSearch("mContext.getOpPackageName()", mCbStub, query,
+                mSessionBinder.prepareFromSearch(mContext.getOpPackageName(), mCbStub, query,
                         extras);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
@@ -746,7 +744,7 @@
                         "You must specify a non-empty Uri for prepareFromUri.");
             }
             try {
-                mSessionBinder.prepareFromUri("mContext.getOpPackageName()", mCbStub, uri, extras);
+                mSessionBinder.prepareFromUri(mContext.getOpPackageName(), mCbStub, uri, extras);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
             }
@@ -757,7 +755,7 @@
          */
         public void play() {
             try {
-                mSessionBinder.play("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.play(mContext.getOpPackageName(), mCbStub);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling play.", e);
             }
@@ -776,7 +774,7 @@
                         "You must specify a non-empty String for playFromMediaId.");
             }
             try {
-                mSessionBinder.playFromMediaId("mContext.getOpPackageName()", mCbStub, mediaId,
+                mSessionBinder.playFromMediaId(mContext.getOpPackageName(), mCbStub, mediaId,
                         extras);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
@@ -799,7 +797,7 @@
                 query = "";
             }
             try {
-                mSessionBinder.playFromSearch("mContext.getOpPackageName()", mCbStub, query, extras);
+                mSessionBinder.playFromSearch(mContext.getOpPackageName(), mCbStub, query, extras);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling play(" + query + ").", e);
             }
@@ -818,7 +816,7 @@
                         "You must specify a non-empty Uri for playFromUri.");
             }
             try {
-                mSessionBinder.playFromUri("mContext.getOpPackageName()", mCbStub, uri, extras);
+                mSessionBinder.playFromUri(mContext.getOpPackageName(), mCbStub, uri, extras);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling play(" + uri + ").", e);
             }
@@ -830,7 +828,7 @@
          */
         public void skipToQueueItem(long id) {
             try {
-                mSessionBinder.skipToQueueItem("mContext.getOpPackageName()", mCbStub, id);
+                mSessionBinder.skipToQueueItem(mContext.getOpPackageName(), mCbStub, id);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
             }
@@ -842,7 +840,7 @@
          */
         public void pause() {
             try {
-                mSessionBinder.pause("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.pause(mContext.getOpPackageName(), mCbStub);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling pause.", e);
             }
@@ -854,7 +852,7 @@
          */
         public void stop() {
             try {
-                mSessionBinder.stop("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.stop(mContext.getOpPackageName(), mCbStub);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling stop.", e);
             }
@@ -867,7 +865,7 @@
          */
         public void seekTo(long pos) {
             try {
-                mSessionBinder.seekTo("mContext.getOpPackageName()", mCbStub, pos);
+                mSessionBinder.seekTo(mContext.getOpPackageName(), mCbStub, pos);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling seekTo.", e);
             }
@@ -879,7 +877,7 @@
          */
         public void fastForward() {
             try {
-                mSessionBinder.fastForward("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.fastForward(mContext.getOpPackageName(), mCbStub);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling fastForward.", e);
             }
@@ -890,7 +888,7 @@
          */
         public void skipToNext() {
             try {
-                mSessionBinder.next("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.next(mContext.getOpPackageName(), mCbStub);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling next.", e);
             }
@@ -902,7 +900,7 @@
          */
         public void rewind() {
             try {
-                mSessionBinder.rewind("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.rewind(mContext.getOpPackageName(), mCbStub);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling rewind.", e);
             }
@@ -913,7 +911,7 @@
          */
         public void skipToPrevious() {
             try {
-                mSessionBinder.previous("mContext.getOpPackageName()", mCbStub);
+                mSessionBinder.previous(mContext.getOpPackageName(), mCbStub);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling previous.", e);
             }
@@ -928,7 +926,7 @@
          */
         public void setRating(Rating rating) {
             try {
-                mSessionBinder.rate("mContext.getOpPackageName()", mCbStub, rating);
+                mSessionBinder.rate(mContext.getOpPackageName(), mCbStub, rating);
             } catch (RemoteException e) {
                 Log.wtf(TAG, "Error calling rate.", e);
             }
@@ -963,7 +961,7 @@
                 throw new IllegalArgumentException("CustomAction cannot be null.");
             }
             try {
-                mSessionBinder.sendCustomAction("mContext.getOpPackageName()", mCbStub, action, args);
+                mSessionBinder.sendCustomAction(mContext.getOpPackageName(), mCbStub, action, args);
             } catch (RemoteException e) {
                 Log.d(TAG, "Dead object in sendCustomAction.", e);
             }