diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index 1096df4..9323d6d 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -55,6 +55,8 @@
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BUS),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_PROXY),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_USB_HEADSET),
+    MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_HEARING_AID),
+    MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ECHO_CANCELLER),
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_DEFAULT),
     // STUB must be after DEFAULT, so the latter is picked up by toString first.
     MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_STUB),
@@ -115,9 +117,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_DIRECT_PCM),
     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ),
     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_VOIP_RX),
-    // FIXME: this cast will be removed when the flag will be
-    // declared in types.hal for audio HAL V4.0 and auto imported to audio-base.h
-    {"AUDIO_OUTPUT_FLAG_INCALL_MUSIC", static_cast<audio_output_flags_t>(AUDIO_OUTPUT_FLAG_INCALL_MUSIC)},
+    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_INCALL_MUSIC),
     TERMINATOR
 };
 
@@ -131,6 +131,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_SYNC),
     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_MMAP_NOIRQ),
     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_VOIP_TX),
+    MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_HW_AV_SYNC),
     TERMINATOR
 };
 
@@ -157,6 +158,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LD),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_HE_V2),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ELD),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_XHE),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ADTS_MAIN),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ADTS_LC),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ADTS_SSR),
@@ -167,6 +169,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ADTS_LD),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V2),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ADTS_ELD),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ADTS_XHE),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_VORBIS),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_HE_AAC_V1),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_HE_AAC_V2),
@@ -197,6 +200,11 @@
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_APTX_HD),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AC4),
     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_LDAC),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MAT),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_E_AC3_JOC),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MAT_1_0),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MAT_2_0),
+    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MAT_2_1),
     TERMINATOR
 };
 
@@ -206,10 +214,18 @@
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_MONO),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_STEREO),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_2POINT1),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_2POINT0POINT2),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_2POINT1POINT2),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_3POINT0POINT2),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_3POINT1POINT2),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_QUAD),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_QUAD_BACK),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_QUAD_SIDE),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_SURROUND),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_PENTA),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_5POINT1_BACK),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_5POINT1_SIDE),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_6POINT1),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
     TERMINATOR
@@ -222,6 +238,11 @@
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_STEREO),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_6),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_2POINT0POINT2),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_2POINT1POINT2),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_3POINT0POINT2),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_3POINT1POINT2),
+    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_5POINT1),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO),
     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_VOICE_CALL_MONO),
diff --git a/media/libstagefright/BufferImpl.cpp b/media/libstagefright/BufferImpl.cpp
index d2eee33..7b3fa02 100644
--- a/media/libstagefright/BufferImpl.cpp
+++ b/media/libstagefright/BufferImpl.cpp
@@ -70,6 +70,10 @@
     if (const_cast<Codec2Buffer *>(this)->base() == nullptr) {
         return false;
     }
+    if (!buffer) {
+        // Nothing to copy, so we can copy by doing nothing.
+        return true;
+    }
     if (buffer->data().type() != C2BufferData::LINEAR) {
         return false;
     }
@@ -89,7 +93,7 @@
 
 bool Codec2Buffer::copyLinear(const std::shared_ptr<C2Buffer> &buffer) {
     // We assume that all canCopyLinear() checks passed.
-    if (buffer->data().linearBlocks().size() == 0u) {
+    if (!buffer || buffer->data().linearBlocks().size() == 0u) {
         setRange(0, 0);
         return true;
     }
@@ -207,4 +211,445 @@
     return std::move(mBufferRef);
 }
 
+// GraphicView2MediaImageConverter
+
+namespace {
+
+class GraphicView2MediaImageConverter {
+public:
+    explicit GraphicView2MediaImageConverter(const C2GraphicView &view)
+        : mInitCheck(NO_INIT),
+          mView(view),
+          mWidth(view.width()),
+          mHeight(view.height()),
+          mAllocatedDepth(0),
+          mBackBufferSize(0),
+          mMediaImage(new ABuffer(sizeof(MediaImage2))) {
+        if (view.error() != C2_OK) {
+            ALOGD("Converter: view.error() = %d", view.error());
+            mInitCheck = BAD_VALUE;
+            return;
+        }
+        MediaImage2 *mediaImage = (MediaImage2 *)mMediaImage->base();
+        const C2PlanarLayout &layout = view.layout();
+        if (layout.numPlanes == 0) {
+            ALOGD("Converter: 0 planes");
+            mInitCheck = BAD_VALUE;
+            return;
+        }
+        mAllocatedDepth = layout.planes[0].allocatedDepth;
+        uint32_t bitDepth = layout.planes[0].bitDepth;
+
+        switch (layout.type) {
+            case C2PlanarLayout::TYPE_YUV:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV; break;
+            case C2PlanarLayout::TYPE_YUVA:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUVA; break;
+            case C2PlanarLayout::TYPE_RGB:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGB; break;
+            case C2PlanarLayout::TYPE_RGBA:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGBA; break;
+            default:
+                mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN; break;
+        }
+        mediaImage->mNumPlanes = layout.numPlanes;
+        mediaImage->mWidth = mWidth;
+        mediaImage->mHeight = mHeight;
+        mediaImage->mBitDepth = bitDepth;
+        mediaImage->mBitDepthAllocated = mAllocatedDepth;
+
+        uint32_t bufferSize = 0;
+        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+            const C2PlaneInfo &plane = layout.planes[i];
+            if (plane.rightShift != 0) {
+                ALOGV("rightShift value of %u unsupported", plane.rightShift);
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            if (plane.endianness != C2PlaneInfo::NATIVE) {
+                ALOGV("endianness value of %u unsupported", plane.endianness);
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            if (plane.allocatedDepth != mAllocatedDepth || plane.bitDepth != bitDepth) {
+                ALOGV("different allocatedDepth/bitDepth per plane unsupported");
+                mInitCheck = BAD_VALUE;
+                return;
+            }
+            bufferSize += mWidth * mHeight
+                    / plane.rowSampling / plane.colSampling * (plane.allocatedDepth / 8);
+        }
+
+        mBackBufferSize = bufferSize;
+        mInitCheck = OK;
+    }
+
+    status_t initCheck() const { return mInitCheck; }
+
+    uint32_t backBufferSize() const { return mBackBufferSize; }
+
+    /**
+     * Convert C2GraphicView to MediaImage2. Note that if not wrapped, the content
+     * is not copied over in this function --- the caller should use
+     * CopyGraphicView2MediaImage() function to do that explicitly.
+     *
+     * \param   view[in]          source C2GraphicView object.
+     * \param   alloc[in]         allocator function for ABuffer.
+     * \param   mediaImage[out]   destination MediaImage2 object.
+     * \param   buffer[out]       new buffer object.
+     * \param   wrapped[out]      whether we wrapped around existing map or
+     *                            allocated a new buffer
+     *
+     * \return  true              if conversion succeeds,
+     *          false             otherwise; all output params should be ignored.
+     */
+    sp<ABuffer> wrap() {
+        MediaImage2 *mediaImage = getMediaImage();
+        const C2PlanarLayout &layout = mView.layout();
+        if (layout.numPlanes == 1) {
+            const C2PlaneInfo &plane = layout.planes[0];
+            ssize_t offset = plane.minOffset(mWidth, mHeight);
+            mediaImage->mPlane[0].mOffset = -offset;
+            mediaImage->mPlane[0].mColInc = plane.colInc;
+            mediaImage->mPlane[0].mRowInc = plane.rowInc;
+            mediaImage->mPlane[0].mHorizSubsampling = plane.colSampling;
+            mediaImage->mPlane[0].mVertSubsampling = plane.rowSampling;
+            return new ABuffer(
+                    const_cast<uint8_t *>(mView.data()[0] + offset),
+                    plane.maxOffset(mWidth, mHeight) - offset + 1);
+        }
+        const uint8_t *minPtr = mView.data()[0];
+        const uint8_t *maxPtr = mView.data()[0];
+        int32_t planeSize = 0;
+        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+            const C2PlaneInfo &plane = layout.planes[i];
+            ssize_t minOffset = plane.minOffset(mWidth, mHeight);
+            ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
+            if (minPtr > mView.data()[i] + minOffset) {
+                minPtr = mView.data()[i] + minOffset;
+            }
+            if (maxPtr < mView.data()[i] + maxOffset) {
+                maxPtr = mView.data()[i] + maxOffset;
+            }
+            planeSize += std::abs(plane.rowInc) * mHeight
+                    / plane.rowSampling / plane.colSampling * (mAllocatedDepth / 8);
+        }
+
+        if ((maxPtr - minPtr + 1) <= planeSize) {
+            // FIXME: this is risky as reading/writing data out of bound results in
+            //        an undefined behavior.
+            for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+                const C2PlaneInfo &plane = layout.planes[i];
+                mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
+                mediaImage->mPlane[i].mColInc = plane.colInc;
+                mediaImage->mPlane[i].mRowInc = plane.rowInc;
+                mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
+                mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+            }
+            return new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
+        }
+
+        return nullptr;
+    }
+
+    bool setBackBuffer(const sp<ABuffer> &backBuffer) {
+        if (backBuffer->capacity() < mBackBufferSize) {
+            return false;
+        }
+        backBuffer->setRange(0, mBackBufferSize);
+
+        const C2PlanarLayout &layout = mView.layout();
+        MediaImage2 *mediaImage = getMediaImage();
+        uint32_t offset = 0;
+        // TODO: keep interleaved planes together
+        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+            const C2PlaneInfo &plane = layout.planes[i];
+            mediaImage->mPlane[i].mOffset = offset;
+            mediaImage->mPlane[i].mColInc = mAllocatedDepth / 8;
+            mediaImage->mPlane[i].mRowInc =
+                mediaImage->mPlane[i].mColInc * mWidth / plane.colSampling;
+            mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
+            mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+            offset += mediaImage->mPlane[i].mRowInc * mHeight / plane.rowSampling;
+        }
+        mBackBuffer = backBuffer;
+        return true;
+    }
+
+    /**
+     * Copy C2GraphicView to MediaImage2. This function assumes that |mediaImage| is
+     * an output from GraphicView2MediaImage(), so it mostly skips sanity check.
+     *
+     * \param   view[in]          source C2GraphicView object.
+     * \param   mediaImage[in]    destination MediaImage2 object.
+     * \param   buffer[out]       new buffer object.
+     */
+    void copy() {
+        // TODO: more efficient copying --- e.g. one row at a time, copying
+        //       interleaved planes together, etc.
+        const C2PlanarLayout &layout = mView.layout();
+        MediaImage2 *mediaImage = getMediaImage();
+        uint8_t *dst = mBackBuffer->base();
+        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+            const C2PlaneInfo &plane = layout.planes[i];
+            const uint8_t *src = mView.data()[i];
+            int32_t planeW = mWidth / plane.colSampling;
+            int32_t planeH = mHeight / plane.rowSampling;
+            for (int32_t row = 0; row < planeH; ++row) {
+                for(int32_t col = 0; col < planeW; ++col) {
+                    memcpy(dst, src, mAllocatedDepth / 8);
+                    dst += mediaImage->mPlane[i].mColInc;
+                    src += plane.colInc;
+                }
+                dst -= mediaImage->mPlane[i].mColInc * planeW;
+                dst += mediaImage->mPlane[i].mRowInc;
+                src -= plane.colInc * planeW;
+                src += plane.rowInc;
+            }
+        }
+    }
+
+    const sp<ABuffer> &imageData() const { return mMediaImage; }
+
+private:
+    status_t mInitCheck;
+
+    const C2GraphicView mView;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mAllocatedDepth;
+    uint32_t mBackBufferSize;
+    sp<ABuffer> mMediaImage;
+    std::function<sp<ABuffer>(size_t)> mAlloc;
+
+    sp<ABuffer> mBackBuffer;
+
+    MediaImage2 *getMediaImage() {
+        return (MediaImage2 *)mMediaImage->base();
+    }
+};
+
+}  // namespace
+
+// GraphicBlockBuffer
+
+// static
+sp<GraphicBlockBuffer> GraphicBlockBuffer::Allocate(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2GraphicBlock> &block,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    C2GraphicView view(block->map().get());
+    if (view.error() != C2_OK) {
+        ALOGD("C2GraphicBlock::map failed: %d", view.error());
+        return nullptr;
+    }
+    GraphicView2MediaImageConverter converter(view);
+    if (converter.initCheck() != OK) {
+        ALOGD("Converter init failed: %d", converter.initCheck());
+        return nullptr;
+    }
+    bool wrapped = true;
+    sp<ABuffer> buffer = converter.wrap();
+    if (buffer == nullptr) {
+        buffer = alloc(converter.backBufferSize());
+        if (!converter.setBackBuffer(buffer)) {
+            ALOGD("Converter failed to set back buffer");
+            return nullptr;
+        }
+        wrapped = false;
+    }
+    return new GraphicBlockBuffer(
+            format,
+            buffer,
+            std::move(view),
+            block,
+            converter.imageData(),
+            wrapped);
+}
+
+GraphicBlockBuffer::GraphicBlockBuffer(
+        const sp<AMessage> &format,
+        const sp<ABuffer> &buffer,
+        C2GraphicView &&view,
+        const std::shared_ptr<C2GraphicBlock> &block,
+        const sp<ABuffer> &imageData,
+        bool wrapped)
+    : Codec2Buffer(format, buffer),
+      mView(view),
+      mBlock(block),
+      mImageData(imageData),
+      mWrapped(wrapped) {
+    meta()->setBuffer("image-data", imageData);
+}
+
+std::shared_ptr<C2Buffer> GraphicBlockBuffer::asC2Buffer() {
+    uint32_t width = mView.width();
+    uint32_t height = mView.height();
+    if (!mWrapped) {
+        MediaImage2 *mediaImage = imageData();
+        const C2PlanarLayout &layout = mView.layout();
+        for (uint32_t i = 0; i < mediaImage->mNumPlanes; ++i) {
+            const C2PlaneInfo &plane = layout.planes[i];
+            int32_t planeW = width / plane.colSampling;
+            int32_t planeH = height / plane.rowSampling;
+            const uint8_t *src = base() + mediaImage->mPlane[i].mOffset;
+            uint8_t *dst = mView.data()[i];
+            for (int32_t row = 0; row < planeH; ++row) {
+                for (int32_t col = 0; col < planeW; ++col) {
+                    memcpy(dst, src, mediaImage->mBitDepthAllocated / 8);
+                    src += mediaImage->mPlane[i].mColInc;
+                    dst += plane.colInc;
+                }
+                src -= mediaImage->mPlane[i].mColInc * planeW;
+                dst -= plane.colInc * planeW;
+                src += mediaImage->mPlane[i].mRowInc;
+                dst += plane.rowInc;
+            }
+        }
+    }
+    return C2Buffer::CreateGraphicBuffer(
+            mBlock->share(C2Rect(width, height), C2Fence()));
+}
+
+// ConstGraphicBlockBuffer
+
+// static
+sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::Allocate(
+        const sp<AMessage> &format,
+        const std::shared_ptr<C2Buffer> &buffer,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    if (!buffer
+            || buffer->data().type() != C2BufferData::GRAPHIC
+            || buffer->data().graphicBlocks().size() != 1u) {
+        ALOGD("C2Buffer precond fail");
+        return nullptr;
+    }
+    std::unique_ptr<const C2GraphicView> view(std::make_unique<const C2GraphicView>(
+            buffer->data().graphicBlocks()[0].map().get()));
+    std::unique_ptr<const C2GraphicView> holder;
+
+    GraphicView2MediaImageConverter converter(*view);
+    if (converter.initCheck() != OK) {
+        ALOGD("Converter init failed: %d", converter.initCheck());
+        return nullptr;
+    }
+    bool wrapped = true;
+    sp<ABuffer> aBuffer = converter.wrap();
+    if (aBuffer == nullptr) {
+        aBuffer = alloc(converter.backBufferSize());
+        if (!converter.setBackBuffer(aBuffer)) {
+            ALOGD("Converter failed to set back buffer");
+            return nullptr;
+        }
+        wrapped = false;
+        converter.copy();
+        // We don't need the view.
+        holder = std::move(view);
+    }
+    return new ConstGraphicBlockBuffer(
+            format,
+            aBuffer,
+            std::move(view),
+            buffer,
+            converter.imageData(),
+            wrapped);
+}
+
+// static
+sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::AllocateEmpty(
+        const sp<AMessage> &format,
+        std::function<sp<ABuffer>(size_t)> alloc) {
+    int32_t width, height;
+    if (!format->findInt32("width", &width)
+            || !format->findInt32("height", &height)) {
+        ALOGD("format had no width / height");
+        return nullptr;
+    }
+    sp<ABuffer> aBuffer(alloc(width * height * 4));
+    return new ConstGraphicBlockBuffer(
+            format,
+            aBuffer,
+            nullptr,
+            nullptr,
+            nullptr,
+            false);
+}
+
+ConstGraphicBlockBuffer::ConstGraphicBlockBuffer(
+        const sp<AMessage> &format,
+        const sp<ABuffer> &aBuffer,
+        std::unique_ptr<const C2GraphicView> &&view,
+        const std::shared_ptr<C2Buffer> &buffer,
+        const sp<ABuffer> &imageData,
+        bool wrapped)
+    : Codec2Buffer(format, aBuffer),
+      mView(std::move(view)),
+      mBufferRef(buffer),
+      mWrapped(wrapped) {
+    if (imageData != nullptr) {
+        meta()->setBuffer("image-data", imageData);
+    }
+}
+
+std::shared_ptr<C2Buffer> ConstGraphicBlockBuffer::asC2Buffer() {
+    mView.reset();
+    return std::move(mBufferRef);
+}
+
+bool ConstGraphicBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
+    if (mWrapped || mBufferRef) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: %swrapped ; buffer ref %s",
+                mWrapped ? "" : "not ", mBufferRef ? "exists" : "doesn't exist");
+        return false;
+    }
+    if (!buffer) {
+        // Nothing to copy, so we can copy by doing nothing.
+        return true;
+    }
+    if (buffer->data().type() != C2BufferData::GRAPHIC) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: buffer precondition unsatisfied");
+        return false;
+    }
+    if (buffer->data().graphicBlocks().size() == 0) {
+        return true;
+    } else if (buffer->data().graphicBlocks().size() != 1u) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: too many blocks");
+        return false;
+    }
+    GraphicView2MediaImageConverter converter(
+            buffer->data().graphicBlocks()[0].map().get());
+    if (converter.initCheck() != OK) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
+        return false;
+    }
+    if (converter.backBufferSize() > capacity()) {
+        ALOGD("ConstGraphicBlockBuffer::canCopy: insufficient capacity: req %u has %zu",
+                converter.backBufferSize(), capacity());
+        return false;
+    }
+    return true;
+}
+
+bool ConstGraphicBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
+    if (!buffer || buffer->data().graphicBlocks().size() == 0) {
+        setRange(0, 0);
+        return true;
+    }
+    GraphicView2MediaImageConverter converter(
+            buffer->data().graphicBlocks()[0].map().get());
+    if (converter.initCheck() != OK) {
+        ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
+        return false;
+    }
+    sp<ABuffer> aBuffer = new ABuffer(base(), capacity());
+    if (!converter.setBackBuffer(aBuffer)) {
+        ALOGD("ConstGraphicBlockBuffer::copy: set back buffer failed");
+        return false;
+    }
+    converter.copy();
+    meta()->setBuffer("image-data", converter.imageData());
+    mBufferRef = buffer;
+    return true;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/CCodec.cpp b/media/libstagefright/CCodec.cpp
index f62ee41..0bdd808 100644
--- a/media/libstagefright/CCodec.cpp
+++ b/media/libstagefright/CCodec.cpp
@@ -238,14 +238,25 @@
     return mChannel;
 }
 
+status_t CCodec::tryAndReportOnError(std::function<status_t()> job) {
+    status_t err = job();
+    if (err != C2_OK) {
+        mCallback->onError(err, ACTION_CODE_FATAL);
+    }
+    return err;
+}
+
 void CCodec::initiateAllocateComponent(const sp<AMessage> &msg) {
-    {
+    auto setAllocating = [this] {
         Mutexed<State>::Locked state(mState);
         if (state->get() != RELEASED) {
-            mCallback->onError(INVALID_OPERATION, ACTION_CODE_FATAL);
-            return;
+            return INVALID_OPERATION;
         }
         state->set(ALLOCATING);
+        return OK;
+    };
+    if (tryAndReportOnError(setAllocating) != OK) {
+        return;
     }
 
     AString componentName;
@@ -259,7 +270,7 @@
 }
 
 void CCodec::allocate(const AString &componentName) {
-    // TODO: use C2ComponentStore to create component
+    ALOGV("allocate(%s)", componentName.c_str());
     mListener.reset(new CCodecListener(this));
 
     std::shared_ptr<C2Component> comp;
@@ -282,29 +293,30 @@
     }
     ALOGV("Success Create component: %s", componentName.c_str());
     comp->setListener_vb(mListener, C2_MAY_BLOCK);
-    {
+    mChannel->setComponent(comp);
+    auto setAllocated = [this, comp] {
         Mutexed<State>::Locked state(mState);
         if (state->get() != ALLOCATING) {
             state->set(RELEASED);
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
+            return UNKNOWN_ERROR;
         }
         state->set(ALLOCATED);
         state->comp = comp;
+        return OK;
+    };
+    if (tryAndReportOnError(setAllocated) != OK) {
+        return;
     }
-    mChannel->setComponent(comp);
     mCallback->onComponentAllocated(comp->intf()->getName().c_str());
 }
 
 void CCodec::initiateConfigureComponent(const sp<AMessage> &format) {
-    {
+    auto checkAllocated = [this] {
         Mutexed<State>::Locked state(mState);
-        if (state->get() != ALLOCATED) {
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            return;
-        }
+        return (state->get() != ALLOCATED) ? UNKNOWN_ERROR : OK;
+    };
+    if (tryAndReportOnError(checkAllocated) != OK) {
+        return;
     }
 
     sp<AMessage> msg(new AMessage(kWhatConfigure, this));
@@ -314,21 +326,22 @@
 
 void CCodec::configure(const sp<AMessage> &msg) {
     std::shared_ptr<C2ComponentInterface> intf;
-    {
+    auto checkAllocated = [this, &intf] {
         Mutexed<State>::Locked state(mState);
         if (state->get() != ALLOCATED) {
             state->set(RELEASED);
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
+            return UNKNOWN_ERROR;
         }
         intf = state->comp->intf();
+        return OK;
+    };
+    if (tryAndReportOnError(checkAllocated) != OK) {
+        return;
     }
 
     sp<AMessage> inputFormat(new AMessage);
     sp<AMessage> outputFormat(new AMessage);
-    if (status_t err = [=] {
+    auto doConfig = [=] {
         AString mime;
         if (!msg->findString("mime", &mime)) {
             return BAD_VALUE;
@@ -339,6 +352,11 @@
             encoder = false;
         }
 
+        // TODO: read from intf()
+        if ((!encoder) != (intf->getName().find("encoder") == std::string::npos)) {
+            return UNKNOWN_ERROR;
+        }
+
         sp<RefBase> obj;
         if (msg->findObject("native-window", &obj)) {
             sp<Surface> surface = static_cast<Surface *>(obj.get());
@@ -386,14 +404,22 @@
             if (audio) {
                 outputFormat->setInt32("channel-count", 2);
                 outputFormat->setInt32("sample-rate", 44100);
+            } else {
+                int32_t tmp;
+                if (msg->findInt32("width", &tmp)) {
+                    outputFormat->setInt32("width", tmp);
+                }
+                if (msg->findInt32("height", &tmp)) {
+                    outputFormat->setInt32("height", tmp);
+                }
             }
         }
 
         // TODO
 
         return OK;
-    }() != OK) {
-        mCallback->onError(err, ACTION_CODE_FATAL);
+    };
+    if (tryAndReportOnError(doConfig) != OK) {
         return;
     }
 
@@ -406,6 +432,22 @@
 }
 
 void CCodec::initiateCreateInputSurface() {
+    status_t err = [this] {
+        Mutexed<State>::Locked state(mState);
+        if (state->get() != ALLOCATED) {
+            return UNKNOWN_ERROR;
+        }
+        // TODO: read it from intf() properly.
+        if (state->comp->intf()->getName().find("encoder") == std::string::npos) {
+            return INVALID_OPERATION;
+        }
+        return OK;
+    }();
+    if (err != OK) {
+        mCallback->onInputSurfaceCreationFailed(err);
+        return;
+    }
+
     (new AMessage(kWhatCreateInputSurface, this))->post();
 }
 
@@ -477,15 +519,16 @@
 }
 
 void CCodec::initiateStart() {
-    {
+    auto setStarting = [this] {
         Mutexed<State>::Locked state(mState);
         if (state->get() != ALLOCATED) {
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
+            return UNKNOWN_ERROR;
         }
         state->set(STARTING);
+        return OK;
+    };
+    if (tryAndReportOnError(setStarting) != OK) {
+        return;
     }
 
     (new AMessage(kWhatStart, this))->post();
@@ -493,16 +536,18 @@
 
 void CCodec::start() {
     std::shared_ptr<C2Component> comp;
-    {
+    auto checkStarting = [this, &comp] {
         Mutexed<State>::Locked state(mState);
         if (state->get() != STARTING) {
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
+            return UNKNOWN_ERROR;
         }
         comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkStarting) != OK) {
+        return;
     }
+
     c2_status_t err = comp->start();
     if (err != C2_OK) {
         // TODO: convert err into status_t
@@ -516,17 +561,22 @@
         inputFormat = formats->inputFormat;
         outputFormat = formats->outputFormat;
     }
-    mChannel->start(inputFormat, outputFormat);
+    status_t err2 = mChannel->start(inputFormat, outputFormat);
+    if (err2 != OK) {
+        mCallback->onError(err2, ACTION_CODE_FATAL);
+        return;
+    }
 
-    {
+    auto setRunning = [this] {
         Mutexed<State>::Locked state(mState);
         if (state->get() != STARTING) {
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
+            return UNKNOWN_ERROR;
         }
         state->set(RUNNING);
+        return OK;
+    };
+    if (tryAndReportOnError(setRunning) != OK) {
+        return;
     }
     mCallback->onStartCompleted();
 }
@@ -652,13 +702,26 @@
 }
 
 void CCodec::signalFlush() {
-    {
+    status_t err = [this] {
         Mutexed<State>::Locked state(mState);
+        if (state->get() == FLUSHED) {
+            return ALREADY_EXISTS;
+        }
         if (state->get() != RUNNING) {
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            return;
+            return UNKNOWN_ERROR;
         }
         state->set(FLUSHING);
+        return OK;
+    }();
+    switch (err) {
+        case ALREADY_EXISTS:
+            mCallback->onFlushCompleted();
+            return;
+        case OK:
+            break;
+        default:
+            mCallback->onError(err, ACTION_CODE_FATAL);
+            return;
     }
 
     (new AMessage(kWhatFlush, this))->post();
@@ -666,15 +729,16 @@
 
 void CCodec::flush() {
     std::shared_ptr<C2Component> comp;
-    {
+    auto checkFlushing = [this, &comp] {
         Mutexed<State>::Locked state(mState);
         if (state->get() != FLUSHING) {
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
+            return UNKNOWN_ERROR;
         }
         comp = state->comp;
+        return OK;
+    };
+    if (tryAndReportOnError(checkFlushing) != OK) {
+        return;
     }
 
     mChannel->stop();
@@ -696,18 +760,19 @@
 }
 
 void CCodec::signalResume() {
-    {
+    auto setResuming = [this] {
         Mutexed<State>::Locked state(mState);
         if (state->get() != FLUSHED) {
-            state.unlock();
-            mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-            state.lock();
-            return;
+            return UNKNOWN_ERROR;
         }
         state->set(RESUMING);
+        return OK;
+    };
+    if (tryAndReportOnError(setResuming) != OK) {
+        return;
     }
 
-    mChannel->start(nullptr, nullptr);
+    (void)mChannel->start(nullptr, nullptr);
 
     {
         Mutexed<State>::Locked state(mState);
@@ -727,6 +792,8 @@
 }
 
 void CCodec::signalEndOfInputStream() {
+    // TODO
+    mCallback->onSignaledInputEOS(INVALID_OPERATION);
 }
 
 void CCodec::signalRequestIDRFrame() {
@@ -735,9 +802,7 @@
 
 void CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) {
     Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
-    for (std::unique_ptr<C2Work> &item : workItems) {
-        queue->push_back(std::move(item));
-    }
+    queue->splice(queue->end(), workItems);
     (new AMessage(kWhatWorkDone, this))->post();
 }
 
@@ -834,8 +899,8 @@
     }
 
     ALOGW("previous call to %s exceeded timeout", name.c_str());
-    mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
     initiateRelease(false);
+    mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
 }
 
 }  // namespace android
diff --git a/media/libstagefright/CCodecBufferChannel.cpp b/media/libstagefright/CCodecBufferChannel.cpp
index 5ce49d9..65d637b 100644
--- a/media/libstagefright/CCodecBufferChannel.cpp
+++ b/media/libstagefright/CCodecBufferChannel.cpp
@@ -60,7 +60,10 @@
     /**
      * Set format for MediaCodec-facing buffers.
      */
-    void setFormat(const sp<AMessage> &format) { mFormat = format; }
+    void setFormat(const sp<AMessage> &format) {
+        CHECK(format != nullptr);
+        mFormat = format;
+    }
 
     /**
      * Returns true if the buffers are operating under array mode.
@@ -179,21 +182,158 @@
 const static size_t kMinBufferArraySize = 16;
 const static size_t kLinearBufferSize = 524288;
 
-sp<LinearBlockBuffer> allocateLinearBuffer(
+/**
+ * Simple local buffer pool backed by std::vector.
+ */
+class LocalBufferPool : public std::enable_shared_from_this<LocalBufferPool> {
+public:
+    /**
+     * Create a new LocalBufferPool object.
+     *
+     * \param poolCapacity  max total size of buffers managed by this pool.
+     *
+     * \return  a newly created pool object.
+     */
+    static std::shared_ptr<LocalBufferPool> Create(size_t poolCapacity) {
+        return std::shared_ptr<LocalBufferPool>(new LocalBufferPool(poolCapacity));
+    }
+
+    /**
+     * Return an ABuffer object whose size is at least |capacity|.
+     *
+     * \param   capacity  requested capacity
+     * \return  nullptr if the pool capacity is reached
+     *          an ABuffer object otherwise.
+     */
+    sp<ABuffer> newBuffer(size_t capacity) {
+        Mutex::Autolock lock(mMutex);
+        auto it = std::find_if(
+                mPool.begin(), mPool.end(),
+                [capacity](const std::vector<uint8_t> &vec) {
+                    return vec.capacity() >= capacity;
+                });
+        if (it != mPool.end()) {
+            sp<ABuffer> buffer = new VectorBuffer(std::move(*it), shared_from_this());
+            mPool.erase(it);
+            return buffer;
+        }
+        if (mUsedSize + capacity > mPoolCapacity) {
+            while (!mPool.empty()) {
+                mUsedSize -= mPool.back().capacity();
+                mPool.pop_back();
+            }
+            if (mUsedSize + capacity > mPoolCapacity) {
+                ALOGD("mUsedSize = %zu, capacity = %zu, mPoolCapacity = %zu",
+                        mUsedSize, capacity, mPoolCapacity);
+                return nullptr;
+            }
+        }
+        std::vector<uint8_t> vec(capacity);
+        mUsedSize += vec.capacity();
+        return new VectorBuffer(std::move(vec), shared_from_this());
+    }
+
+private:
+    /**
+     * ABuffer backed by std::vector.
+     */
+    class VectorBuffer : public ::android::ABuffer {
+    public:
+        /**
+         * Construct a VectorBuffer by taking the ownership of supplied vector.
+         *
+         * \param vec   backing vector of the buffer. this object takes
+         *              ownership at construction.
+         * \param pool  a LocalBufferPool object to return the vector at
+         *              destruction.
+         */
+        VectorBuffer(std::vector<uint8_t> &&vec, const std::shared_ptr<LocalBufferPool> &pool)
+            : ABuffer(vec.data(), vec.capacity()),
+              mVec(std::move(vec)),
+              mPool(pool) {
+        }
+
+        ~VectorBuffer() override {
+            std::shared_ptr<LocalBufferPool> pool = mPool.lock();
+            if (pool) {
+                // If pool is alive, return the vector back to the pool so that
+                // it can be recycled.
+                pool->returnVector(std::move(mVec));
+            }
+        }
+
+    private:
+        std::vector<uint8_t> mVec;
+        std::weak_ptr<LocalBufferPool> mPool;
+    };
+
+    Mutex mMutex;
+    size_t mPoolCapacity;
+    size_t mUsedSize;
+    std::list<std::vector<uint8_t>> mPool;
+
+    /**
+     * Private constructor to prevent constructing non-managed LocalBufferPool.
+     */
+    explicit LocalBufferPool(size_t poolCapacity)
+        : mPoolCapacity(poolCapacity), mUsedSize(0) {
+    }
+
+    /**
+     * Take back the ownership of vec from the destructed VectorBuffer and put
+     * it in front of the pool.
+     */
+    void returnVector(std::vector<uint8_t> &&vec) {
+        Mutex::Autolock lock(mMutex);
+        mPool.push_front(std::move(vec));
+    }
+
+    DISALLOW_EVIL_CONSTRUCTORS(LocalBufferPool);
+};
+
+sp<LinearBlockBuffer> AllocateLinearBuffer(
         const std::shared_ptr<C2BlockPool> &pool,
         const sp<AMessage> &format,
         size_t size,
         const C2MemoryUsage &usage) {
     std::shared_ptr<C2LinearBlock> block;
 
-    status_t err = pool->fetchLinearBlock(size, usage, &block);
-    if (err != OK) {
+    c2_status_t err = pool->fetchLinearBlock(size, usage, &block);
+    if (err != C2_OK) {
         return nullptr;
     }
 
     return LinearBlockBuffer::Allocate(format, block);
 }
 
+sp<GraphicBlockBuffer> AllocateGraphicBuffer(
+        const std::shared_ptr<C2BlockPool> &pool,
+        const sp<AMessage> &format,
+        uint32_t pixelFormat,
+        const C2MemoryUsage &usage,
+        const std::shared_ptr<LocalBufferPool> &localBufferPool) {
+    int32_t width, height;
+    if (!format->findInt32("width", &width) || !format->findInt32("height", &height)) {
+        ALOGD("format lacks width or height");
+        return nullptr;
+    }
+
+    std::shared_ptr<C2GraphicBlock> block;
+    c2_status_t err = pool->fetchGraphicBlock(
+            width, height, pixelFormat, usage, &block);
+    if (err != C2_OK) {
+        ALOGD("fetch graphic block failed: %d", err);
+        return nullptr;
+    }
+
+    return GraphicBlockBuffer::Allocate(
+            format,
+            block,
+            [localBufferPool](size_t capacity) {
+                return localBufferPool->newBuffer(capacity);
+            });
+}
+
 class BuffersArrayImpl;
 
 /**
@@ -383,6 +523,7 @@
 class InputBuffersArray : public CCodecBufferChannel::InputBuffers {
 public:
     InputBuffersArray() = default;
+    ~InputBuffersArray() override = default;
 
     void initialize(
             const FlexBuffersImpl &impl,
@@ -432,7 +573,8 @@
         // TODO: proper max input size
         // TODO: read usage from intf
         C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        sp<LinearBlockBuffer> newBuffer = allocateLinearBuffer(mPool, mFormat, kLinearBufferSize, usage);
+        sp<LinearBlockBuffer> newBuffer = AllocateLinearBuffer(
+                mPool, mFormat, kLinearBufferSize, usage);
         if (newBuffer == nullptr) {
             return false;
         }
@@ -458,7 +600,7 @@
                 kMinBufferArraySize,
                 [pool = mPool, format = mFormat] () -> sp<Codec2Buffer> {
                     C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-                    return allocateLinearBuffer(pool, format, kLinearBufferSize, usage);
+                    return AllocateLinearBuffer(pool, format, kLinearBufferSize, usage);
                 });
         return std::move(array);
     }
@@ -469,7 +611,54 @@
 
 class GraphicInputBuffers : public CCodecBufferChannel::InputBuffers {
 public:
-    GraphicInputBuffers() = default;
+    GraphicInputBuffers() : mLocalBufferPool(LocalBufferPool::Create(1920 * 1080 * 16)) {}
+    ~GraphicInputBuffers() override = default;
+
+    bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
+        // TODO: proper max input size
+        // TODO: read usage from intf
+        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+        sp<GraphicBlockBuffer> newBuffer = AllocateGraphicBuffer(
+                mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool);
+        if (newBuffer == nullptr) {
+            return false;
+        }
+        *index = mImpl.assignSlot(newBuffer);
+        *buffer = newBuffer;
+        return true;
+    }
+
+    std::shared_ptr<C2Buffer> releaseBuffer(const sp<MediaCodecBuffer> &buffer) override {
+        return mImpl.releaseSlot(buffer);
+    }
+
+    void flush() override {
+        // This is no-op by default unless we're in array mode where we need to keep
+        // track of the flushed work.
+    }
+
+    std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode() final {
+        std::unique_ptr<InputBuffersArray> array(new InputBuffersArray);
+        array->setFormat(mFormat);
+        array->initialize(
+                mImpl,
+                kMinBufferArraySize,
+                [pool = mPool, format = mFormat, lbp = mLocalBufferPool]() -> sp<Codec2Buffer> {
+                    C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+                    return AllocateGraphicBuffer(
+                            pool, format, HAL_PIXEL_FORMAT_YV12, usage, lbp);
+                });
+        return std::move(array);
+    }
+
+private:
+    FlexBuffersImpl mImpl;
+    std::shared_ptr<LocalBufferPool> mLocalBufferPool;
+};
+
+class DummyInputBuffers : public CCodecBufferChannel::InputBuffers {
+public:
+    DummyInputBuffers() = default;
 
     bool requestNewBuffer(size_t *, sp<MediaCodecBuffer> *) override {
         return false;
@@ -495,7 +684,8 @@
 
 class OutputBuffersArray : public CCodecBufferChannel::OutputBuffers {
 public:
-    using CCodecBufferChannel::OutputBuffers::OutputBuffers;
+    OutputBuffersArray() = default;
+    ~OutputBuffersArray() override = default;
 
     void initialize(
             const FlexBuffersImpl &impl,
@@ -522,12 +712,14 @@
                     return clientBuffer->canCopy(buffer);
                 });
         if (err != OK) {
-            return false;
-        }
-        if (!c2Buffer->copy(buffer)) {
+            ALOGD("grabBuffer failed: %d", err);
             return false;
         }
         c2Buffer->setFormat(mFormat);
+        if (!c2Buffer->copy(buffer)) {
+            ALOGD("copy buffer failed");
+            return false;
+        }
         *clientBuffer = c2Buffer;
         return true;
     }
@@ -585,6 +777,7 @@
             size_t *index,
             sp<MediaCodecBuffer> *clientBuffer) override {
         sp<Codec2Buffer> newBuffer = wrap(buffer);
+        newBuffer->setFormat(mFormat);
         *index = mImpl.assignSlot(newBuffer);
         *clientBuffer = newBuffer;
         return true;
@@ -627,8 +820,21 @@
         return std::move(array);
     }
 
+    /**
+     * Return an appropriate Codec2Buffer object for the type of buffers.
+     *
+     * \param buffer  C2Buffer object to wrap.
+     *
+     * \return  appropriate Codec2Buffer object to wrap |buffer|.
+     */
     virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0;
 
+    /**
+     * Return an appropriate Codec2Buffer object for the type of buffers, to be
+     * used as an empty array buffer.
+     *
+     * \return  appropriate Codec2Buffer object which can copy() from C2Buffers.
+     */
     virtual sp<Codec2Buffer> allocateArrayBuffer() = 0;
 
 private:
@@ -673,6 +879,34 @@
     }
 };
 
+class RawGraphicOutputBuffers : public FlexOutputBuffers {
+public:
+    RawGraphicOutputBuffers()
+        : mLocalBufferPool(LocalBufferPool::Create(1920 * 1080 * 16)) {
+    }
+    ~RawGraphicOutputBuffers() override = default;
+
+    sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
+        return ConstGraphicBlockBuffer::Allocate(
+                mFormat,
+                buffer,
+                [lbp = mLocalBufferPool](size_t capacity) {
+                    return lbp->newBuffer(capacity);
+                });
+    }
+
+    sp<Codec2Buffer> allocateArrayBuffer() override {
+        return ConstGraphicBlockBuffer::AllocateEmpty(
+                mFormat,
+                [lbp = mLocalBufferPool](size_t capacity) {
+                    return lbp->newBuffer(capacity);
+                });
+    }
+
+private:
+    std::shared_ptr<LocalBufferPool> mLocalBufferPool;
+};
+
 }  // namespace
 
 CCodecBufferChannel::QueueGuard::QueueGuard(
@@ -735,55 +969,6 @@
 
 void CCodecBufferChannel::setComponent(const std::shared_ptr<C2Component> &component) {
     mComponent = component;
-
-    C2StreamFormatConfig::input inputFormat(0u);
-    C2StreamFormatConfig::output outputFormat(0u);
-    c2_status_t err = mComponent->intf()->query_vb(
-            { &inputFormat, &outputFormat },
-            {},
-            C2_DONT_BLOCK,
-            nullptr);
-    if (err != C2_OK) {
-        // TODO: error
-        return;
-    }
-
-    {
-        Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-
-        bool graphic = (inputFormat.value == C2FormatVideo);
-        if (graphic) {
-            buffers->reset(new GraphicInputBuffers);
-        } else {
-            buffers->reset(new LinearInputBuffers);
-        }
-
-        ALOGV("graphic = %s", graphic ? "true" : "false");
-        std::shared_ptr<C2BlockPool> pool;
-        if (graphic) {
-            err = GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, component, &pool);
-        } else {
-            err = CreateCodec2BlockPool(C2PlatformAllocatorStore::ION,
-                                        component, &pool);
-        }
-
-        if (err == C2_OK) {
-            (*buffers)->setPool(pool);
-        } else {
-            // TODO: error
-        }
-    }
-
-    {
-        Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-
-        bool graphic = (outputFormat.value == C2FormatVideo);
-        if (graphic) {
-            buffers->reset(new GraphicOutputBuffers);
-        } else {
-            buffers->reset(new LinearOutputBuffers);
-        }
-    }
 }
 
 status_t CCodecBufferChannel::setInputSurface(
@@ -812,6 +997,7 @@
     if (buffer->meta()->findInt32("csd", &tmp) && tmp) {
         flags |= C2FrameData::FLAG_CODEC_CONFIG;
     }
+    ALOGV("queueInputBuffer: buffer->size() = %zu", buffer->size());
     std::unique_ptr<C2Work> work(new C2Work);
     work->input.flags = (C2FrameData::flags_t)flags;
     work->input.ordinal.timestamp = timeUs;
@@ -968,13 +1154,68 @@
     (*buffers)->getArray(array);
 }
 
-void CCodecBufferChannel::start(const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
+status_t CCodecBufferChannel::start(
+        const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
+    C2StreamFormatConfig::input iStreamFormat(0u);
+    C2StreamFormatConfig::output oStreamFormat(0u);
+    c2_status_t err = mComponent->intf()->query_vb(
+            { &iStreamFormat, &oStreamFormat },
+            {},
+            C2_DONT_BLOCK,
+            nullptr);
+    if (err != C2_OK) {
+        return UNKNOWN_ERROR;
+    }
+
     if (inputFormat != nullptr) {
         Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
+
+        bool graphic = (iStreamFormat.value == C2FormatVideo);
+        if (graphic) {
+            if (mInputSurface) {
+                buffers->reset(new DummyInputBuffers);
+            } else {
+                buffers->reset(new GraphicInputBuffers);
+            }
+        } else {
+            buffers->reset(new LinearInputBuffers);
+        }
         (*buffers)->setFormat(inputFormat);
+
+        ALOGV("graphic = %s", graphic ? "true" : "false");
+        std::shared_ptr<C2BlockPool> pool;
+        if (graphic) {
+            err = GetCodec2BlockPool(C2BlockPool::BASIC_GRAPHIC, mComponent, &pool);
+        } else {
+            err = CreateCodec2BlockPool(C2PlatformAllocatorStore::ION,
+                                        mComponent, &pool);
+        }
+        if (err == C2_OK) {
+            (*buffers)->setPool(pool);
+        } else {
+            // TODO: error
+        }
     }
+
     if (outputFormat != nullptr) {
+        bool hasOutputSurface = false;
+        {
+            Mutexed<sp<Surface>>::Locked surface(mSurface);
+            hasOutputSurface = (*surface != nullptr);
+        }
+
         Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
+
+        bool graphic = (oStreamFormat.value == C2FormatVideo);
+        if (graphic) {
+            if (hasOutputSurface) {
+                buffers->reset(new GraphicOutputBuffers);
+            } else {
+                buffers->reset(new RawGraphicOutputBuffers);
+            }
+        } else {
+            buffers->reset(new LinearOutputBuffers);
+        }
         (*buffers)->setFormat(outputFormat);
     }
 
@@ -989,9 +1230,7 @@
                 if (!(*buffers)->requestNewBuffer(&index, &buffer)) {
                     if (i == 0) {
                         ALOGE("start: cannot allocate memory at all");
-                        buffers.unlock();
-                        mOnError(NO_MEMORY, ACTION_CODE_FATAL);
-                        buffers.lock();
+                        return NO_MEMORY;
                     } else {
                         ALOGV("start: cannot allocate memory, only %zu buffers allocated", i);
                     }
@@ -1003,6 +1242,7 @@
     } else {
         (void)mInputSurface->connect(mComponent);
     }
+    return OK;
 }
 
 void CCodecBufferChannel::stop() {
@@ -1010,6 +1250,7 @@
     mFirstValidFrameIndex = mFrameIndex.load();
     if (mInputSurface != nullptr) {
         mInputSurface->disconnect();
+        mInputSurface.reset();
     }
 }
 
@@ -1025,8 +1266,13 @@
 }
 
 void CCodecBufferChannel::onWorkDone(const std::unique_ptr<C2Work> &work) {
-    if (work->result != OK) {
-        ALOGE("work failed to complete: %d", work->result);
+    if (work->result != C2_OK) {
+        if (work->result == C2_NOT_FOUND) {
+            // TODO: Define what flushed work's result is.
+            ALOGD("flushed work; ignored.");
+            return;
+        }
+        ALOGD("work failed to complete: %d", work->result);
         mOnError(work->result, ACTION_CODE_FATAL);
         return;
     }
diff --git a/media/libstagefright/codec2/SimpleC2Component.cpp b/media/libstagefright/codec2/SimpleC2Component.cpp
index 0753b08..f3d95f6 100644
--- a/media/libstagefright/codec2/SimpleC2Component.cpp
+++ b/media/libstagefright/codec2/SimpleC2Component.cpp
@@ -51,6 +51,8 @@
     mQueue.push_back({ nullptr, drainMode });
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
 SimpleC2Component::SimpleC2Component(
         const std::shared_ptr<C2ComponentInterface> &intf)
     : mIntf(intf) {
@@ -91,13 +93,13 @@
 }
 
 c2_status_t SimpleC2Component::announce_nb(const std::vector<C2WorkOutline> &items) {
-    (void) items;
+    (void)items;
     return C2_OMITTED;
 }
 
 c2_status_t SimpleC2Component::flush_sm(
-        flush_mode_t flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
-    (void) flushThrough;
+        flush_mode_t flushMode, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
+    (void)flushMode;
     {
         Mutexed<ExecState>::Locked state(mExecState);
         if (state->mState != RUNNING) {
@@ -107,6 +109,7 @@
     {
         Mutexed<WorkQueue>::Locked queue(mWorkQueue);
         queue->incGeneration();
+        // TODO: queue->splicedBy(flushedWork, flushedWork->end());
         while (!queue->empty()) {
             std::unique_ptr<C2Work> work = queue->pop_front();
             if (work) {
@@ -122,7 +125,7 @@
         }
     }
 
-    return onFlush_sm();
+    return C2_OK;
 }
 
 c2_status_t SimpleC2Component::drain_nb(drain_mode_t drainMode) {
@@ -160,6 +163,10 @@
     }
     if (!state->mThread.joinable()) {
         mExitRequested = false;
+        {
+            Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
+            monitor->mExited = false;
+        }
         state->mThread = std::thread(
                 [](std::weak_ptr<SimpleC2Component> wp) {
                     while (true) {
@@ -168,6 +175,8 @@
                             return;
                         }
                         if (thiz->exitRequested()) {
+                            ALOGV("stop processing");
+                            thiz->signalExit();
                             return;
                         }
                         thiz->processQueue();
@@ -179,7 +188,42 @@
     return C2_OK;
 }
 
+void SimpleC2Component::signalExit() {
+    Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
+    monitor->mExited = true;
+    monitor->mCondition.broadcast();
+}
+
+void SimpleC2Component::requestExitAndWait(std::function<void()> job) {
+    {
+        Mutexed<ExecState>::Locked state(mExecState);
+        if (!state->mThread.joinable()) {
+            return;
+        }
+    }
+    mExitRequested = true;
+    {
+        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
+        queue->mCondition.broadcast();
+    }
+    // TODO: timeout?
+    {
+        Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
+        while (!monitor->mExited) {
+            monitor.waitForCondition(monitor->mCondition);
+        }
+        job();
+    }
+    Mutexed<ExecState>::Locked state(mExecState);
+    if (state->mThread.joinable()) {
+        ALOGV("joining the processing thread");
+        state->mThread.join();
+        ALOGV("joined the processing thread");
+    }
+}
+
 c2_status_t SimpleC2Component::stop() {
+    ALOGV("stop");
     {
         Mutexed<ExecState>::Locked state(mExecState);
         if (state->mState != RUNNING) {
@@ -195,7 +239,8 @@
         Mutexed<PendingWork>::Locked pending(mPendingWork);
         pending->clear();
     }
-    c2_status_t err = onStop();
+    c2_status_t err;
+    requestExitAndWait([this, &err]{ err = onStop(); });
     if (err != C2_OK) {
         return err;
     }
@@ -203,6 +248,7 @@
 }
 
 c2_status_t SimpleC2Component::reset() {
+    ALOGV("reset");
     {
         Mutexed<ExecState>::Locked state(mExecState);
         state->mState = UNINITIALIZED;
@@ -215,21 +261,13 @@
         Mutexed<PendingWork>::Locked pending(mPendingWork);
         pending->clear();
     }
-    onReset();
+    requestExitAndWait([this]{ onReset(); });
     return C2_OK;
 }
 
 c2_status_t SimpleC2Component::release() {
-    std::thread releasing;
-    {
-        Mutexed<ExecState>::Locked state(mExecState);
-        releasing = std::move(state->mThread);
-    }
-    mExitRequested = true;
-    if (releasing.joinable()) {
-        releasing.join();
-    }
-    onRelease();
+    ALOGV("release");
+    requestExitAndWait([this]{ onRelease(); });
     return C2_OK;
 }
 
@@ -271,10 +309,14 @@
     std::unique_ptr<C2Work> work;
     uint64_t generation;
     int32_t drainMode;
+    bool isFlushPending = false;
     {
         Mutexed<WorkQueue>::Locked queue(mWorkQueue);
         nsecs_t deadline = systemTime() + ms2ns(250);
         while (queue->empty()) {
+            if (exitRequested()) {
+                return;
+            }
             nsecs_t now = systemTime();
             if (now >= deadline) {
                 return;
@@ -287,8 +329,17 @@
 
         generation = queue->generation();
         drainMode = queue->drainMode();
+        isFlushPending = queue->popPendingFlush();
         work = queue->pop_front();
     }
+    if (isFlushPending) {
+        ALOGV("processing pending flush");
+        c2_status_t err = onFlush_sm();
+        if (err != C2_OK) {
+            ALOGD("flush err: %d", err);
+            // TODO: error
+        }
+    }
 
     if (!mOutputBlockPool) {
         c2_status_t err = [this] {
@@ -333,10 +384,12 @@
     }
 
     process(work, mOutputBlockPool);
+    ALOGV("processed frame #%" PRIu64, work->input.ordinal.frameIndex.peeku());
     {
         Mutexed<WorkQueue>::Locked queue(mWorkQueue);
         if (queue->generation() != generation) {
-            ALOGW("work form old generation: was %" PRIu64 " now %" PRIu64, queue->generation(), generation);
+            ALOGD("work form old generation: was %" PRIu64 " now %" PRIu64,
+                    queue->generation(), generation);
             work->result = C2_NOT_FOUND;
             queue.unlock();
             {
@@ -361,9 +414,10 @@
                 unexpected = std::move(pending->at(frameIndex));
                 pending->erase(frameIndex);
             }
-            (void) pending->insert({ frameIndex, std::move(work) });
+            (void)pending->insert({ frameIndex, std::move(work) });
         }
         if (unexpected) {
+            ALOGD("unexpected pending work");
             unexpected->result = C2_CORRUPTED;
             Mutexed<ExecState>::Locked state(mExecState);
             state->mListener->onWorkDone_nb(shared_from_this(), vec(unexpected));
diff --git a/media/libstagefright/codec2/include/SimpleC2Component.h b/media/libstagefright/codec2/include/SimpleC2Component.h
index a4b6ee1..168e79f 100644
--- a/media/libstagefright/codec2/include/SimpleC2Component.h
+++ b/media/libstagefright/codec2/include/SimpleC2Component.h
@@ -52,6 +52,7 @@
     // for thread
     inline bool exitRequested() { return mExitRequested; }
     void processQueue();
+    void signalExit();
 
 protected:
     /**
@@ -157,16 +158,21 @@
 
     class WorkQueue {
     public:
-        inline WorkQueue() : mGeneration(0ul) {}
+        inline WorkQueue() : mFlush(false), mGeneration(0ul) {}
 
         inline uint64_t generation() const { return mGeneration; }
-        inline void incGeneration() { ++mGeneration; }
+        inline void incGeneration() { ++mGeneration; mFlush = true; }
 
         std::unique_ptr<C2Work> pop_front();
         void push_back(std::unique_ptr<C2Work> work);
         bool empty() const;
         uint32_t drainMode() const;
         void markDrain(uint32_t drainMode);
+        inline bool popPendingFlush() {
+            bool flush = mFlush;
+            mFlush = false;
+            return flush;
+        }
         void clear();
 
         Condition mCondition;
@@ -177,6 +183,7 @@
             uint32_t drainMode;
         };
 
+        bool mFlush;
         uint64_t mGeneration;
         std::list<Entry> mQueue;
     };
@@ -185,9 +192,18 @@
     typedef std::unordered_map<uint64_t, std::unique_ptr<C2Work>> PendingWork;
     Mutexed<PendingWork> mPendingWork;
 
+    struct ExitMonitor {
+        inline ExitMonitor() : mExited(false) {}
+        Condition mCondition;
+        bool mExited;
+    };
+    Mutexed<ExitMonitor> mExitMonitor;
+
     std::shared_ptr<C2BlockPool> mOutputBlockPool;
 
     SimpleC2Component() = delete;
+
+    void requestExitAndWait(std::function<void()> job);
 };
 
 }  // namespace android
diff --git a/media/libstagefright/codec2/vndk/C2Buffer.cpp b/media/libstagefright/codec2/vndk/C2Buffer.cpp
index 91b21c2..af2c20d 100644
--- a/media/libstagefright/codec2/vndk/C2Buffer.cpp
+++ b/media/libstagefright/codec2/vndk/C2Buffer.cpp
@@ -647,7 +647,8 @@
     std::shared_ptr<_C2BlockPoolData> mPoolData;
 };
 
-class C2_HIDE _C2MappingBlock2DImpl : public _C2Block2DImpl {
+class C2_HIDE _C2MappingBlock2DImpl
+    : public _C2Block2DImpl, public std::enable_shared_from_this<_C2MappingBlock2DImpl> {
 public:
     using _C2Block2DImpl::_C2Block2DImpl;
 
@@ -658,7 +659,7 @@
     private:
         friend class _C2MappingBlock2DImpl;
 
-        Mapped(const _C2Block2DImpl *impl, bool writable, C2Fence *fence __unused)
+        Mapped(const std::shared_ptr<_C2Block2DImpl> &impl, bool writable, C2Fence *fence __unused)
             : mImpl(impl), mWritable(writable) {
             memset(mData, 0, sizeof(mData));
             const C2Rect crop = mImpl->crop();
@@ -726,7 +727,7 @@
         bool writable() const { return mWritable; }
 
     private:
-        const _C2Block2DImpl *mImpl;
+        const std::shared_ptr<_C2Block2DImpl> mImpl;
         bool mWritable;
         c2_status_t mError;
         uint8_t *mData[C2PlanarLayout::MAX_NUM_PLANES];
@@ -744,7 +745,7 @@
         std::lock_guard<std::mutex> lock(mMappedLock);
         std::shared_ptr<Mapped> existing = mMapped.lock();
         if (!existing) {
-            existing = std::shared_ptr<Mapped>(new Mapped(this, writable, fence));
+            existing = std::shared_ptr<Mapped>(new Mapped(shared_from_this(), writable, fence));
             mMapped = existing;
         } else {
             // if we mapped the region read-only, we cannot remap it read-write
diff --git a/media/libstagefright/codecs/aacdec/C2SoftAac.cpp b/media/libstagefright/codecs/aacdec/C2SoftAac.cpp
index c82ea45..6bd15a5 100644
--- a/media/libstagefright/codecs/aacdec/C2SoftAac.cpp
+++ b/media/libstagefright/codecs/aacdec/C2SoftAac.cpp
@@ -305,37 +305,57 @@
         ALOGV("getting %d from ringbuffer", numSamples);
 
         std::shared_ptr<C2LinearBlock> block;
-        C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
-        // TODO: error handling, proper usage, etc.
-        c2_status_t err = pool->fetchLinearBlock(numSamples * sizeof(int16_t), usage, &block);
-        if (err != C2_OK) {
-            ALOGE("err = %d", err);
-        }
+        std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
+            [&block, numSamples, pool, this]()
+                    -> std::function<void(const std::unique_ptr<C2Work>&)> {
+                auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work, c2_status_t err) {
+                    work->result = err;
+                    work->worklets.front()->output.flags = work->input.flags;
+                    work->worklets.front()->output.buffers.clear();
+                    work->worklets.front()->output.ordinal = work->input.ordinal;
+                    work->workletsProcessed = 1u;
+                };
 
-        C2WriteView wView = block->map().get();
-        // TODO
-        INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
-        int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
-        if (ns != numSamples) {
-            ALOGE("not a complete frame of samples available");
-            mSignalledError = true;
-            // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-            return;
-        }
-        auto fillWork = [buffer = createLinearBuffer(block)](const std::unique_ptr<C2Work> &work) {
-            work->worklets.front()->output.flags = work->input.flags;
-            work->worklets.front()->output.buffers.clear();
-            work->worklets.front()->output.buffers.push_back(buffer);
-            work->worklets.front()->output.ordinal = work->input.ordinal;
-            work->workletsProcessed = 1u;
-        };
+                using namespace std::placeholders;
+                if (numSamples == 0) {
+                    return std::bind(fillEmptyWork, _1, C2_OK);
+                }
+
+                // TODO: error handling, proper usage, etc.
+                C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
+                c2_status_t err = pool->fetchLinearBlock(
+                        numSamples * sizeof(int16_t), usage, &block);
+                if (err != C2_OK) {
+                    ALOGD("failed to fetch a linear block (%d)", err);
+                    mSignalledError = true;
+                    return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
+                }
+                C2WriteView wView = block->map().get();
+                // TODO
+                INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
+                int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
+                if (ns != numSamples) {
+                    ALOGE("not a complete frame of samples available");
+                    mSignalledError = true;
+                    return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
+                }
+                return [buffer = createLinearBuffer(block)](const std::unique_ptr<C2Work> &work) {
+                    work->result = C2_OK;
+                    work->worklets.front()->output.flags = work->input.flags;
+                    work->worklets.front()->output.buffers.clear();
+                    work->worklets.front()->output.buffers.push_back(buffer);
+                    work->worklets.front()->output.ordinal = work->input.ordinal;
+                    work->workletsProcessed = 1u;
+                };
+            }();
+
         if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
             fillWork(work);
         } else {
             finish(outInfo.frameIndex, fillWork);
         }
 
-        ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block->capacity());
+        ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
         mBuffersInfo.pop_front();
     }
 }
diff --git a/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.cpp b/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.cpp
index 4dd0309..406d1ca 100644
--- a/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/C2SoftAmrNbEnc.cpp
@@ -115,7 +115,7 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer = work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
     bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
index b9ba251..1fc2c8c 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
@@ -37,15 +37,6 @@
 
 #include "ih264d_defs.h"
 
-namespace {
-
-template <class T>
-inline int32_t floor32(T arg) {
-   return (int32_t) std::llround(std::floor(arg));
-}
-
-} // namespace
-
 namespace android {
 
 struct iv_obj_t : public ::iv_obj_t {};
@@ -83,138 +74,19 @@
             .build();
 }
 
-#if 0
-using SupportedValuesWithFields = C2SoftAvcDecIntf::SupportedValuesWithFields;
-
-struct ValidateParam {
-    explicit ValidateParam(
-            const std::map<C2ParamField, SupportedValuesWithFields> &supportedValues)
-        : mSupportedValues(supportedValues) {}
-
-    template <class T, bool SIGNED = std::is_signed<T>::value, size_t SIZE = sizeof(T)>
-    struct Getter {
-        static T get(const C2Value::Primitive &) {
-            static_assert(!std::is_arithmetic<T>::value, "non-arithmetic type");
-            static_assert(!std::is_floating_point<T>::value || std::is_same<T, float>::value,
-                    "float is the only supported floating point type");
-            static_assert(sizeof(T) <= 8, "type exceeds 64-bit");
+void CopyPlane(
+        uint8_t *dst, const C2PlaneInfo &plane,
+        const uint8_t *src, uint32_t width, uint32_t height) {
+    for (uint32_t row = 0; row < height; ++row) {
+        for (uint32_t col = 0; col < width; ++col) {
+            *dst = *src;
+            dst += plane.colInc;
+            ++src;
         }
-    };
-
-    template <class T>
-    bool validateField(
-            const C2FieldSupportedValues &supportedValues, const T &value) {
-        switch (supportedValues.type) {
-        case C2FieldSupportedValues::EMPTY:
-            {
-                return false;
-            }
-        case C2FieldSupportedValues::RANGE:
-            {
-                // TODO: handle step, num, denom
-                return Getter<T>::get(supportedValues.range.min) <= value
-                        && value <= Getter<T>::get(supportedValues.range.max);
-            }
-        case C2FieldSupportedValues::VALUES:
-            {
-                for (const auto &val : supportedValues.values) {
-                    if (Getter<T>::get(val) == value) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        case C2FieldSupportedValues::FLAGS:
-            // TODO
-            return false;
-        }
-        return false;
+        dst -= plane.colInc * width;
+        dst += plane.rowInc;
     }
-
-protected:
-    const std::map<C2ParamField, SupportedValuesWithFields> &mSupportedValues;
-};
-
-template <>
-struct ValidateParam::Getter<float> {
-    static float get(const C2Value::Primitive &value) { return value.fp; }
-};
-template <class T>
-struct ValidateParam::Getter<T, true, 8u> {
-    static int64_t get(const C2Value::Primitive &value) { return value.i64; }
-};
-template <class T>
-struct ValidateParam::Getter<T, true, 4u> {
-    static int32_t get(const C2Value::Primitive &value) { return value.i32; }
-};
-template <class T>
-struct ValidateParam::Getter<T, false, 8u> {
-    static uint64_t get(const C2Value::Primitive &value) { return value.u64; }
-};
-template <class T>
-struct ValidateParam::Getter<T, false, 4u> {
-    static uint32_t get(const C2Value::Primitive &value) { return value.u32; }
-};
-
-template <class T>
-struct ValidateSimpleParam : public ValidateParam {
-    explicit ValidateSimpleParam(
-            const std::map<C2ParamField, SupportedValuesWithFields> &supportedValues)
-        : ValidateParam(supportedValues) {}
-
-    std::unique_ptr<C2SettingResult> operator() (C2Param *c2param) {
-        T* param = (T*)c2param;
-        C2ParamField field(param, &T::value);
-        const C2FieldSupportedValues &supportedValues = mSupportedValues.at(field).supported;
-        if (!validateField(supportedValues, param->value)) {
-            return std::unique_ptr<C2SettingResult>(
-                    new C2SettingResult {C2SettingResult::BAD_VALUE, {field, nullptr}, {}});
-        }
-        return nullptr;
-    }
-};
-
-template <class T>
-struct ValidateVideoSize : public ValidateParam {
-    explicit ValidateVideoSize(
-            const std::map<C2ParamField, SupportedValuesWithFields> &supportedValues)
-        : ValidateParam(supportedValues) {}
-
-    std::unique_ptr<C2SettingResult> operator() (C2Param *c2param) {
-        T* param = (T*)c2param;
-        C2ParamField field(param, &T::width);
-        const C2FieldSupportedValues &supportedWidth = mSupportedValues.at(field).supported;
-        if (!validateField(supportedWidth, param->width)) {
-            return std::unique_ptr<C2SettingResult>(
-                    new C2SettingResult {C2SettingResult::BAD_VALUE, {field, nullptr}, {}});
-        }
-        field = C2ParamField(param, &T::height);
-        const C2FieldSupportedValues &supportedHeight = mSupportedValues.at(field).supported;
-        if (!validateField(supportedHeight, param->height)) {
-            return std::unique_ptr<C2SettingResult>(
-                    new C2SettingResult {C2SettingResult::BAD_VALUE, {field, nullptr}, {}});
-        }
-        return nullptr;
-    }
-};
-
-template <class T>
-struct ValidateCString {
-    explicit ValidateCString(const char *expected) : mExpected(expected) {}
-
-    std::unique_ptr<C2SettingResult> operator() (C2Param *c2param) {
-        T* param = (T*)c2param;
-        if (strncmp(param->m.value, mExpected, param->flexCount()) != 0) {
-            return std::unique_ptr<C2SettingResult>(
-                    new C2SettingResult {C2SettingResult::BAD_VALUE, {C2ParamField(param, &T::m), nullptr}, {}});
-        }
-        return nullptr;
-    }
-
-private:
-    const char *mExpected;
-};
-#endif
+}
 
 void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
     uint32_t flags = 0;
@@ -229,398 +101,6 @@
 
 }  // namespace
 
-#if 0
-#define CASE(member) \
-    case decltype(component->member)::CORE_INDEX: \
-        return std::unique_ptr<C2StructDescriptor>(new C2StructDescriptor( \
-                static_cast<decltype(component->member) *>(nullptr)))
-
-class C2SoftAvcDecIntf::ParamReflector : public C2ParamReflector {
-public:
-    virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex coreIndex) override {
-        constexpr C2SoftAvcDecIntf *component = nullptr;
-        switch (coreIndex.coreIndex()) {
-        CASE(mDomainInfo);
-        CASE(mInputStreamCount);
-        CASE(mInputStreamFormat);
-        // Output counterparts for the above would be redundant.
-        CASE(mVideoSize);
-        CASE(mMaxVideoSizeHint);
-
-        // port mime configs are stored as unique_ptr.
-        case C2PortMimeConfig::CORE_INDEX:
-            return std::unique_ptr<C2StructDescriptor>(new C2StructDescriptor(
-                    static_cast<C2PortMimeConfig *>(nullptr)));
-        }
-        return nullptr;
-    }
-};
-#undef CASE
-
-// static const CodecProfileLevel kProfileLevels[] = {
-//     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel52 },
-//     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel52 },
-//     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel52 },
-// };
-C2SoftAvcDecIntf::C2SoftAvcDecIntf(const char *name, c2_node_id_t id)
-    : mName(name),
-      mId(id),
-      mDomainInfo(C2DomainVideo),
-      mInputStreamCount(1u),
-      mOutputStreamCount(1u),
-      mInputStreamFormat(0u, C2FormatCompressed),
-      mOutputStreamFormat(0u, C2FormatVideo),
-      mProfile(0u, kAvcProfileUnknown),
-      mLevel(0u, kAvcLevelUnknown),
-      mBlockSize(0u),
-      mAlignment(0u),
-      mFrameRate(0u, 0),
-      mBlocksPerSecond(0u, 0),
-      mParamReflector(new ParamReflector) {
-    ALOGV("in %s", __func__);
-    mInputPortMime = C2PortMimeConfig::input::AllocUnique(strlen(CODEC_MIME_TYPE) + 1);
-    strcpy(mInputPortMime->m.value, CODEC_MIME_TYPE);
-    mOutputPortMime = C2PortMimeConfig::output::AllocUnique(strlen(MEDIA_MIMETYPE_VIDEO_RAW) + 1);
-    strcpy(mOutputPortMime->m.value, MEDIA_MIMETYPE_VIDEO_RAW);
-
-    mVideoSize.width = 320;
-    mVideoSize.height = 240;
-    mBlockSize.width = 16;
-    mBlockSize.height = 16;
-    mAlignment.width = 2;
-    mAlignment.height = 2;
-
-    mMaxVideoSizeHint.width = H264_MAX_FRAME_WIDTH;
-    mMaxVideoSizeHint.height = H264_MAX_FRAME_HEIGHT;
-
-    mOutputBlockPools = C2PortBlockPoolsTuning::output::AllocUnique({});
-
-    auto insertParam = [&params = mParams] (C2Param *param) {
-        params[param->index()] = param;
-    };
-
-    auto markReadOnly = [&supported = mSupportedValues] (auto *param) {
-        supported.emplace(
-                C2ParamField(param, &std::remove_pointer<decltype(param)>::type::value),
-                C2FieldSupportedValues(false /* flags */, {}));
-    };
-
-    auto markReadOnlyVideoSize = [&supported = mSupportedValues] (auto *param) {
-        supported.emplace(
-                C2ParamField(param, &std::remove_pointer<decltype(param)>::type::width),
-                C2FieldSupportedValues(false /* flags */, {}));
-        supported.emplace(
-                C2ParamField(param, &std::remove_pointer<decltype(param)>::type::height),
-                C2FieldSupportedValues(false /* flags */, {}));
-    };
-
-    insertParam(&mDomainInfo);
-    markReadOnly(&mDomainInfo);
-    mFieldVerifiers[mDomainInfo.index()] =
-            ValidateSimpleParam<decltype(mDomainInfo)>(mSupportedValues);
-
-    insertParam(mInputPortMime.get());
-    mFieldVerifiers[mInputPortMime->index()] =
-            ValidateCString<std::remove_reference<decltype(*mInputPortMime)>::type>(CODEC_MIME_TYPE);
-
-    insertParam(&mInputStreamCount);
-    markReadOnly(&mInputStreamCount);
-    mFieldVerifiers[mInputStreamCount.index()] =
-            ValidateSimpleParam<decltype(mInputStreamCount)>(mSupportedValues);
-
-    insertParam(mOutputPortMime.get());
-    mFieldVerifiers[mOutputPortMime->index()] =
-            ValidateCString<std::remove_reference<decltype(*mOutputPortMime)>::type>(MEDIA_MIMETYPE_VIDEO_RAW);
-
-    insertParam(&mOutputStreamCount);
-    markReadOnly(&mOutputStreamCount);
-    mFieldVerifiers[mOutputStreamCount.index()] =
-            ValidateSimpleParam<decltype(mOutputStreamCount)>(mSupportedValues);
-
-    insertParam(&mInputStreamFormat);
-    markReadOnly(&mInputStreamFormat);
-    mFieldVerifiers[mInputStreamFormat.index()] =
-            ValidateSimpleParam<decltype(mInputStreamFormat)>(mSupportedValues);
-
-    insertParam(&mOutputStreamFormat);
-    markReadOnly(&mOutputStreamFormat);
-    mFieldVerifiers[mOutputStreamFormat.index()] =
-            ValidateSimpleParam<decltype(mOutputStreamFormat)>(mSupportedValues);
-
-    insertParam(&mVideoSize);
-    markReadOnlyVideoSize(&mVideoSize);
-    mFieldVerifiers[mVideoSize.index()] =
-            ValidateVideoSize<decltype(mVideoSize)>(mSupportedValues);
-
-    insertParam(&mMaxVideoSizeHint);
-    mSupportedValues.emplace(
-            C2ParamField(&mMaxVideoSizeHint, &C2MaxVideoSizeHintPortSetting::width),
-            C2FieldSupportedValues(H264_MIN_FRAME_WIDTH, H264_MAX_FRAME_WIDTH, mAlignment.width));
-    mSupportedValues.emplace(
-            C2ParamField(&mMaxVideoSizeHint, &C2MaxVideoSizeHintPortSetting::height),
-            C2FieldSupportedValues(H264_MIN_FRAME_HEIGHT, H264_MAX_FRAME_HEIGHT, mAlignment.height));
-    mFieldVerifiers[mMaxVideoSizeHint.index()] =
-            ValidateVideoSize<decltype(mMaxVideoSizeHint)>(mSupportedValues);
-
-    insertParam(&mProfile);
-    mSupportedValues.emplace(
-            C2ParamField(&mProfile, &C2AvcProfileInfo::value),
-            C2FieldSupportedValues(false /* flags */, {
-                kAvcProfileUnknown,
-                kAvcProfileBaseline,
-                kAvcProfileMain,
-                kAvcProfileHigh,
-            }));
-    mFieldVerifiers[mProfile.index()] =
-            ValidateSimpleParam<decltype(mProfile)>(mSupportedValues);
-
-    insertParam(&mLevel);
-    mSupportedValues.emplace(
-            C2ParamField(&mLevel, &C2AvcLevelInfo::value),
-            C2FieldSupportedValues(false /* flags */, {
-                kAvcLevelUnknown,
-                kAvcLevel10,
-                kAvcLevel1b,
-                kAvcLevel11,
-                kAvcLevel12,
-                kAvcLevel13,
-                kAvcLevel20,
-                kAvcLevel21,
-                kAvcLevel22,
-                kAvcLevel30,
-                kAvcLevel31,
-                kAvcLevel32,
-                kAvcLevel40,
-                kAvcLevel41,
-                kAvcLevel42,
-                kAvcLevel50,
-                kAvcLevel51,
-                kAvcLevel52,
-            }));
-    mFieldVerifiers[mLevel.index()] =
-            ValidateSimpleParam<decltype(mLevel)>(mSupportedValues);
-
-    insertParam(&mBlockSize);
-    markReadOnlyVideoSize(&mBlockSize);
-    mFieldVerifiers[mBlockSize.index()] =
-            ValidateVideoSize<decltype(mBlockSize)>(mSupportedValues);
-
-    insertParam(&mAlignment);
-    markReadOnlyVideoSize(&mAlignment);
-    mFieldVerifiers[mAlignment.index()] =
-            ValidateVideoSize<decltype(mAlignment)>(mSupportedValues);
-
-    insertParam(&mFrameRate);
-    mSupportedValues.emplace(
-            C2ParamField(&mFrameRate, &C2FrameRateInfo::value),
-            C2FieldSupportedValues(0, 240));
-    mFieldVerifiers[mFrameRate.index()] =
-            ValidateSimpleParam<decltype(mFrameRate)>(mSupportedValues);
-
-    insertParam(&mBlocksPerSecond);
-    mSupportedValues.emplace(
-            C2ParamField(&mFrameRate, &C2BlocksPerSecondInfo::value),
-            C2FieldSupportedValues(0, 244800));
-    mFieldVerifiers[mBlocksPerSecond.index()] =
-            ValidateSimpleParam<decltype(mBlocksPerSecond)>(mSupportedValues);
-
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            true, "_domain", &mDomainInfo));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            true, "_input_port_mime", mInputPortMime.get()));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            true, "_input_stream_count", &mInputStreamCount));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            true, "_output_port_mime", mOutputPortMime.get()));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            true, "_output_stream_count", &mOutputStreamCount));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            true, "_input_stream_format", &mInputStreamFormat));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            true, "_output_stream_format", &mOutputStreamFormat));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            false, "_video_size", &mVideoSize));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            false, "_max_video_size_hint", &mMaxVideoSizeHint));
-    mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
-            false, "_output_block_pools", mOutputBlockPools.get()));
-}
-
-C2SoftAvcDecIntf::~C2SoftAvcDecIntf() {
-    ALOGV("in %s", __func__);
-}
-
-C2String C2SoftAvcDecIntf::getName() const {
-    return mName;
-}
-
-c2_node_id_t C2SoftAvcDecIntf::getId() const {
-    return mId;
-}
-
-c2_status_t C2SoftAvcDecIntf::query_vb(
-        const std::vector<C2Param*> & stackParams,
-        const std::vector<C2Param::Index> & heapParamIndices,
-        c2_blocking_t mayBlock,
-        std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
-    (void)mayBlock;
-    for (C2Param* const param : stackParams) {
-        if (!*param) {
-            continue;
-        }
-
-        uint32_t index = param->index();
-        if (!mParams.count(index)) {
-            // TODO: add support for output-block-pools (this will be done when we move all
-            // config to shared ptr)
-            continue;
-        }
-
-        C2Param *myParam = mParams.find(index)->second;
-        if (myParam->size() != param->size()) {
-            param->invalidate();
-            continue;
-        }
-
-        param->updateFrom(*myParam);
-    }
-
-    for (const C2Param::Index index : heapParamIndices) {
-        if (mParams.count(index)) {
-            C2Param *myParam = mParams.find(index)->second;
-            heapParams->emplace_back(C2Param::Copy(*myParam));
-        }
-    }
-
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcDecIntf::config_vb(
-        const std::vector<C2Param*> &params,
-        c2_blocking_t mayBlock,
-        std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
-    (void)mayBlock;
-    c2_status_t err = C2_OK;
-    for (C2Param *param : params) {
-        uint32_t index = param->index();
-        if (param->index() == mOutputBlockPools.get()->index()) {
-            // setting output block pools
-            mOutputBlockPools.reset(
-                    (C2PortBlockPoolsTuning::output *)C2Param::Copy(*param).release());
-            continue;
-        }
-
-        if (mParams.count(index) == 0) {
-            // We can't create C2SettingResult with no field, so just skipping in this case.
-            err = C2_BAD_INDEX;
-            continue;
-        }
-        C2Param *myParam = mParams.find(index)->second;
-        std::unique_ptr<C2SettingResult> result;
-        if (!(result = mFieldVerifiers[index](param))) {
-            myParam->updateFrom(*param);
-            updateSupportedValues();
-        } else {
-            failures->push_back(std::move(result));
-            err = C2_BAD_VALUE;
-        }
-    }
-    return err;
-}
-
-c2_status_t C2SoftAvcDecIntf::createTunnel_sm(c2_node_id_t targetComponent) {
-    // Tunneling is not supported
-    (void) targetComponent;
-    return C2_OMITTED;
-}
-
-c2_status_t C2SoftAvcDecIntf::releaseTunnel_sm(c2_node_id_t targetComponent) {
-    // Tunneling is not supported
-    (void) targetComponent;
-    return C2_OMITTED;
-}
-
-std::shared_ptr<C2ParamReflector> C2SoftAvcDecIntf::getParamReflector() const {
-    return mParamReflector;
-}
-
-c2_status_t C2SoftAvcDecIntf::querySupportedParams_nb(
-        std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const {
-    params->insert(params->begin(), mParamDescs.begin(), mParamDescs.end());
-    return C2_OK;
-}
-
-c2_status_t C2SoftAvcDecIntf::querySupportedValues_vb(
-        std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const {
-    (void)mayBlock;
-    c2_status_t res = C2_OK;
-    for (C2FieldSupportedValuesQuery &query : fields) {
-        if (mSupportedValues.count(query.field) == 0) {
-            query.status = C2_BAD_INDEX;
-            res = C2_BAD_INDEX;
-        } else {
-            query.status = C2_OK;
-            query.values = mSupportedValues.at(query.field).supported;
-        }
-    }
-    return res;
-}
-
-void C2SoftAvcDecIntf::updateSupportedValues() {
-    int32_t maxWidth = H264_MAX_FRAME_WIDTH;
-    int32_t maxHeight = H264_MAX_FRAME_HEIGHT;
-    // cf: Rec. ITU-T H.264 A.3
-    int maxFrameRate = 172;
-    std::vector<C2ParamField> fields;
-    if (mLevel.value != kAvcLevelUnknown) {
-        // cf: Rec. ITU-T H.264 Table A-1
-        constexpr int MaxFS[] = {
-        //  0       1       2       3       4       5       6       7       8       9
-            0,      0,      0,      0,      0,      0,      0,      0,      0,      99,
-            99,     396,    396,    396,    0,      0,      0,      0,      0,      0,
-            396,    792,    1620,   0,      0,      0,      0,      0,      0,      0,
-            1620,   3600,   5120,   0,      0,      0,      0,      0,      0,      0,
-            8192,   8192,   8704,   0,      0,      0,      0,      0,      0,      0,
-            22080,  36864,  36864,
-        };
-        constexpr int MaxMBPS[] = {
-        //  0       1       2       3       4       5       6       7       8       9
-            0,      0,      0,      0,      0,      0,      0,      0,      0,      1485,
-            1485,   3000,   6000,   11880,  0,      0,      0,      0,      0,      0,
-            11880,  19800,  20250,  0,      0,      0,      0,      0,      0,      0,
-            40500,  108000, 216000, 0,      0,      0,      0,      0,      0,      0,
-            245760, 245760, 522240, 0,      0,      0,      0,      0,      0,      0,
-            589824, 983040, 2073600,
-        };
-
-        // cf: Rec. ITU-T H.264 A.3.1
-        maxWidth = std::min(maxWidth, floor32(std::sqrt(MaxFS[mLevel.value] * 8)) * MB_SIZE);
-        maxHeight = std::min(maxHeight, floor32(std::sqrt(MaxFS[mLevel.value] * 8)) * MB_SIZE);
-        int32_t MBs = ((mVideoSize.width + 15) / 16) * ((mVideoSize.height + 15) / 16);
-        maxFrameRate = std::min(maxFrameRate, MaxMBPS[mLevel.value] / MBs);
-        fields.push_back(C2ParamField(&mLevel, &C2AvcLevelInfo::value));
-    }
-
-    SupportedValuesWithFields &maxWidthVals = mSupportedValues.at(
-            C2ParamField(&mMaxVideoSizeHint, &C2MaxVideoSizeHintPortSetting::width));
-    maxWidthVals.supported.range.max = maxWidth;
-    maxWidthVals.restrictingFields.clear();
-    maxWidthVals.restrictingFields.insert(fields.begin(), fields.end());
-
-    SupportedValuesWithFields &maxHeightVals = mSupportedValues.at(
-            C2ParamField(&mMaxVideoSizeHint, &C2MaxVideoSizeHintPortSetting::height));
-    maxHeightVals.supported.range.max = maxHeight;
-    maxHeightVals.restrictingFields.clear();
-    maxHeightVals.restrictingFields.insert(fields.begin(), fields.end());
-
-    SupportedValuesWithFields &frameRate = mSupportedValues.at(
-            C2ParamField(&mFrameRate, &C2FrameRateInfo::value));
-    frameRate.supported.range.max = maxFrameRate;
-    frameRate.restrictingFields.clear();
-    frameRate.restrictingFields.insert(fields.begin(), fields.end());
-}
-#endif
-
 ///////////////////////////////////////////////////////////////////////////////
 
 C2SoftAvcDec::C2SoftAvcDec(
@@ -628,7 +108,7 @@
         c2_node_id_t id)
     : SimpleC2Component(BuildIntf(name, id)),
       mCodecCtx(NULL),
-      mFlushOutBuffer(NULL),
+      mOutBuffer(NULL),
       mIvColorFormat(IV_YUV_420P),
       mChangingResolution(false),
       mSignalledError(false),
@@ -654,6 +134,7 @@
 }
 
 c2_status_t C2SoftAvcDec::onStop() {
+    ALOGV("onStop");
     mSignalledError = false;
     resetDecoder();
     resetPlugin();
@@ -662,6 +143,7 @@
 }
 
 void C2SoftAvcDec::onReset() {
+    ALOGV("onReset");
     (void)onStop();
 }
 
@@ -672,17 +154,6 @@
 c2_status_t C2SoftAvcDec::onFlush_sm() {
     setFlushMode();
 
-    /* Allocate a picture buffer to flushed data */
-    uint32_t displayStride = mWidth;
-    uint32_t displayHeight = mHeight;
-
-    uint32_t bufferSize = displayStride * displayHeight * 3 / 2;
-    mFlushOutBuffer = (uint8_t *)memalign(128, bufferSize);
-    if (NULL == mFlushOutBuffer) {
-        ALOGE("Could not allocate flushOutputBuffer of size %u", bufferSize);
-        return C2_NO_MEMORY;
-    }
-
     while (true) {
         ivd_video_decode_ip_t s_dec_ip;
         ivd_video_decode_op_t s_dec_op;
@@ -698,9 +169,9 @@
         }
     }
 
-    if (mFlushOutBuffer) {
-        free(mFlushOutBuffer);
-        mFlushOutBuffer = NULL;
+    if (mOutBuffer) {
+        free(mOutBuffer);
+        mOutBuffer = NULL;
     }
     return C2_OK;
 }
@@ -778,6 +249,16 @@
 
         return UNKNOWN_ERROR;
     }
+
+    if (mOutBuffer != NULL) {
+        free(mOutBuffer);
+    }
+    uint32_t bufferSize = mWidth * mHeight * 3 / 2;
+    mOutBuffer = (uint8_t *)memalign(128, bufferSize);
+    if (NULL == mOutBuffer) {
+        ALOGE("Could not allocate output buffer of size %u", bufferSize);
+        return C2_NO_MEMORY;
+    }
     return OK;
 }
 
@@ -854,6 +335,7 @@
                 s_video_flush_op.u4_error_code);
         return UNKNOWN_ERROR;
     }
+
     return OK;
 }
 
@@ -993,6 +475,7 @@
 
     ps_dec_ip->u4_size = sizeof(ivd_video_decode_ip_t);
     ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t);
+    ps_dec_op->u4_output_present = 0;
 
     ps_dec_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
 
@@ -1020,14 +503,29 @@
                   outBuffer->width(), outBuffer->height(), width, height);
             return false;
         }
+        ALOGV("width = %u, stride[0] = %u, stride[1] = %u, stride[2] = %u",
+                outBuffer->width(),
+                outBuffer->layout().planes[0].rowInc,
+                outBuffer->layout().planes[1].rowInc,
+                outBuffer->layout().planes[2].rowInc);
+        const C2PlanarLayout &layout = outBuffer->layout();
         ps_dec_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[0];
+        if (layout.planes[0].rowInc != (int32_t)mWidth || layout.planes[1].colInc != 1) {
+            ps_dec_ip->s_out_buffer.pu1_bufs[0] = mOutBuffer;
+        }
         ps_dec_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[1];
+        if (layout.planes[1].rowInc != (int32_t)mWidth / 2 || layout.planes[1].colInc != 1) {
+            ps_dec_ip->s_out_buffer.pu1_bufs[1] = mOutBuffer + sizeY;
+        }
         ps_dec_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[2];
+        if (layout.planes[2].rowInc != (int32_t)mWidth / 2 || layout.planes[2].colInc != 1) {
+            ps_dec_ip->s_out_buffer.pu1_bufs[2] = mOutBuffer + sizeY + sizeUV;
+        }
     } else {
-        // mFlushOutBuffer always has the right size.
-        ps_dec_ip->s_out_buffer.pu1_bufs[0] = mFlushOutBuffer;
-        ps_dec_ip->s_out_buffer.pu1_bufs[1] = mFlushOutBuffer + sizeY;
-        ps_dec_ip->s_out_buffer.pu1_bufs[2] = mFlushOutBuffer + sizeY + sizeUV;
+        // mOutBuffer always has the right size.
+        ps_dec_ip->s_out_buffer.pu1_bufs[0] = mOutBuffer;
+        ps_dec_ip->s_out_buffer.pu1_bufs[1] = mOutBuffer + sizeY;
+        ps_dec_ip->s_out_buffer.pu1_bufs[2] = mOutBuffer + sizeY + sizeUV;
     }
 
     ps_dec_ip->s_out_buffer.u4_num_bufs = 3;
@@ -1065,7 +563,8 @@
 }
 
 void C2SoftAvcDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
-    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mAllocatedBlock));
+    std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(mAllocatedBlock);
+    mAllocatedBlock.reset();
     auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
         uint32_t flags = 0;
         if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
@@ -1093,9 +592,9 @@
     work->result = C2_OK;
     work->workletsProcessed = 0u;
 
-    const C2ConstLinearBlock &buffer =
+    const C2ConstLinearBlock buffer =
         work->input.buffers[0]->data().linearBlocks().front();
-    if (buffer.capacity() == 0) {
+    if (buffer.size() == 0) {
         ALOGV("empty input: %llu", work->input.ordinal.frameIndex.peekull());
         // TODO: result?
         fillEmptyWork(work);
@@ -1109,6 +608,13 @@
     }
 
     C2ReadView input = work->input.buffers[0]->data().linearBlocks().front().map().get();
+    if (input.error() != C2_OK) {
+        work->result = input.error();
+        fillEmptyWork(work);
+        ALOGD("map error: %d", input.error());
+        return;
+    }
+    ALOGV("buffer.size() = %u, input.capacity() = %u", buffer.size(), input.capacity());
     uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
     size_t inOffset = 0u;
 
@@ -1117,34 +623,54 @@
             break;
         }
         (void)ensureDecoderState(pool);
-        C2GraphicView output = mAllocatedBlock->map().get();
-        if (output.error() != OK) {
-            ALOGE("mapped err = %d", output.error());
-        }
-
         ivd_video_decode_ip_t s_dec_ip;
         ivd_video_decode_op_t s_dec_op;
         WORD32 timeDelay, timeTaken;
         //size_t sizeY, sizeUV;
 
-        if (!setDecodeArgs(&s_dec_ip, &s_dec_op, &input, &output, workIndex, inOffset)) {
-            ALOGE("Decoder arg setup failed");
-            // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-            mSignalledError = true;
-            break;
+        {
+            C2GraphicView output = mAllocatedBlock->map().get();
+            if (output.error() != C2_OK) {
+                ALOGE("mapped err = %d", output.error());
+                work->result = output.error();
+                fillEmptyWork(work);
+                return;
+            }
+            if (!setDecodeArgs(&s_dec_ip, &s_dec_op, &input, &output, workIndex, inOffset)) {
+                ALOGE("Decoder arg setup failed");
+                // TODO: notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                mSignalledError = true;
+                break;
+            }
+            ALOGV("Decoder arg setup succeeded");
+            // If input dump is enabled, then write to file
+            DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes, mInputOffset);
+
+            GETTIME(&mTimeStart, NULL);
+            /* Compute time elapsed between end of previous decode()
+             * to start of current decode() */
+            TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
+
+            IV_API_CALL_STATUS_T status;
+            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
+            ALOGV("status = %d, error_code = %d", status, (s_dec_op.u4_error_code & 0xFF));
+            if (s_dec_op.u4_output_present) {
+                const C2PlanarLayout &layout = output.layout();
+                if (layout.planes[0].rowInc != (int32_t)mWidth || layout.planes[1].colInc != 1) {
+                    CopyPlane(output.data()[0], layout.planes[0], mOutBuffer, mWidth, mHeight);
+                }
+                if (layout.planes[1].rowInc != (int32_t)mWidth / 2 || layout.planes[1].colInc != 1) {
+                    CopyPlane(
+                            output.data()[1], layout.planes[1],
+                            mOutBuffer + (mWidth * mHeight), mWidth / 2, mHeight / 2);
+                }
+                if (layout.planes[2].rowInc != (int32_t)mWidth / 2 || layout.planes[2].colInc != 1) {
+                    CopyPlane(
+                            output.data()[2], layout.planes[2],
+                            mOutBuffer + (mWidth * mHeight * 5 / 4), mWidth / 2, mHeight / 2);
+                }
+            }
         }
-        ALOGV("Decoder arg setup succeeded");
-        // If input dump is enabled, then write to file
-        DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes, mInputOffset);
-
-        GETTIME(&mTimeStart, NULL);
-        /* Compute time elapsed between end of previous decode()
-         * to start of current decode() */
-        TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
-
-        IV_API_CALL_STATUS_T status;
-        status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
-        ALOGV("status = %d, error_code = %d", status, (s_dec_op.u4_error_code & 0xFF));
 
         bool unsupportedResolution =
             (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & 0xFF));
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
index 6632bf3..d324a0f 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
@@ -189,7 +189,7 @@
     struct timeval mTimeEnd;     // Time at the end of decode()
 
     // Internal buffer to be used to flush out the buffers from decoder
-    uint8_t *mFlushOutBuffer;
+    uint8_t *mOutBuffer;
 
 #ifdef FILE_DUMP_ENABLE
     char mInFile[200];
diff --git a/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.cpp b/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.cpp
index 8fb8122..d75e4c1 100644
--- a/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/C2SoftAvcEnc.cpp
@@ -909,6 +909,9 @@
     }
 
     ALOGV("width = %d, height = %d", input->width(), input->height());
+    if (mWidth != input->width() || mHeight != input->height()) {
+        return C2_BAD_VALUE;
+    }
     const C2PlanarLayout &layout = input->layout();
     uint8_t *yPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_Y]);
     uint8_t *uPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_U]);
diff --git a/media/libstagefright/codecs/cmds/codec2.cpp b/media/libstagefright/codecs/cmds/codec2.cpp
index 5558bcf..295a5b0 100644
--- a/media/libstagefright/codecs/cmds/codec2.cpp
+++ b/media/libstagefright/codecs/cmds/codec2.cpp
@@ -248,7 +248,7 @@
             ALOGV("Render: Frame #%lld", work->worklets.front()->output.ordinal.frameIndex.peekll());
             const std::shared_ptr<C2Buffer> &output = work->worklets.front()->output.buffers[0];
             if (output) {
-                const C2ConstGraphicBlock &block = output->data().graphicBlocks().front();
+                const C2ConstGraphicBlock block = output->data().graphicBlocks().front();
                 native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(block.handle());
                 sp<GraphicBuffer> buffer(new GraphicBuffer(
                         grallocHandle,
diff --git a/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.cpp b/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.cpp
index ce40d6b..0f1fecc 100644
--- a/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.cpp
+++ b/media/libstagefright/codecs/flac/dec/C2SoftFlacDecoder.cpp
@@ -111,7 +111,7 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer = work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
     C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
diff --git a/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.cpp b/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.cpp
index 6c147ad..fa93fe5 100644
--- a/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.cpp
+++ b/media/libstagefright/codecs/flac/enc/C2SoftFlacEnc.cpp
@@ -140,7 +140,7 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer = work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
     bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
diff --git a/media/libstagefright/codecs/g711/dec/C2SoftG711.cpp b/media/libstagefright/codecs/g711/dec/C2SoftG711.cpp
index d296a3d..1049420 100644
--- a/media/libstagefright/codecs/g711/dec/C2SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/C2SoftG711.cpp
@@ -92,8 +92,8 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer =
-	work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer =
+        work->input.buffers[0]->data().linearBlocks().front();
     C2ReadView rView = inBuffer.map().get();
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
diff --git a/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.cpp b/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.cpp
index 2a3239f..641c342 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/C2SoftMpeg4Dec.cpp
@@ -304,7 +304,7 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer = work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
     uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
diff --git a/media/libstagefright/codecs/mp3dec/C2SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/C2SoftMP3.cpp
index 9cac87e..0a8891e 100644
--- a/media/libstagefright/codecs/mp3dec/C2SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/C2SoftMP3.cpp
@@ -288,7 +288,7 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer = work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
     bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
index d443b7c..bc5fd79 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp
@@ -184,7 +184,7 @@
     info->emphasis           = (temp << 30) >> 30;  /* 2 */
 
 
-    if (!info->bitrate_index || info->sampling_frequency == 3)
+    if (!info->bitrate_index || info->bitrate_index == 15 || info->sampling_frequency == 3)
     {
         err = UNSUPPORTED_FREE_BITRATE;
     }
diff --git a/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.cpp b/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.cpp
index 0ebe7d6..74ea340 100644
--- a/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.cpp
+++ b/media/libstagefright/codecs/mpeg2dec/C2SoftMpeg2Dec.cpp
@@ -614,7 +614,7 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer = work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
     uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
diff --git a/media/libstagefright/codecs/on2/dec/C2SoftVpx.cpp b/media/libstagefright/codecs/on2/dec/C2SoftVpx.cpp
index 96b303c..8528f26 100644
--- a/media/libstagefright/codecs/on2/dec/C2SoftVpx.cpp
+++ b/media/libstagefright/codecs/on2/dec/C2SoftVpx.cpp
@@ -209,7 +209,7 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer = work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
     C2ReadView rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
diff --git a/media/libstagefright/codecs/opus/dec/C2SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/C2SoftOpus.cpp
index 4eec362..47fb6de 100644
--- a/media/libstagefright/codecs/opus/dec/C2SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/C2SoftOpus.cpp
@@ -251,7 +251,7 @@
         return;
     }
 
-    const C2ConstLinearBlock &inBuffer = work->input.buffers[0]->data().linearBlocks().front();
+    const C2ConstLinearBlock inBuffer = work->input.buffers[0]->data().linearBlocks().front();
     bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
     size_t inOffset = inBuffer.offset();
     size_t inSize = inBuffer.size();
diff --git a/media/libstagefright/include/CCodecBufferChannel.h b/media/libstagefright/include/CCodecBufferChannel.h
index eb3255f..51eee10 100644
--- a/media/libstagefright/include/CCodecBufferChannel.h
+++ b/media/libstagefright/include/CCodecBufferChannel.h
@@ -88,7 +88,7 @@
      * Start queueing buffers to the component. This object should never queue
      * buffers before this call.
      */
-    void start(const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat);
+    status_t start(const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat);
 
     /**
      * Stop queueing buffers to the component. This object should never queue
diff --git a/media/libstagefright/include/Codec2Buffer.h b/media/libstagefright/include/Codec2Buffer.h
index 9766b41..eeb889d 100644
--- a/media/libstagefright/include/Codec2Buffer.h
+++ b/media/libstagefright/include/Codec2Buffer.h
@@ -20,6 +20,7 @@
 
 #include <C2Buffer.h>
 
+#include <media/hardware/VideoAPI.h>
 #include <media/MediaCodecBuffer.h>
 
 namespace android {
@@ -109,6 +110,11 @@
 public:
     /**
      * Allocate a new LinearBufferBlock wrapping around C2LinearBlock object.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   block   C2LinearBlock object to wrap around.
+     * \return          LinearBlockBuffer object with writable mapping.
+     *                  nullptr if unsuccessful.
      */
     static sp<LinearBlockBuffer> Allocate(
             const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block);
@@ -137,6 +143,11 @@
 public:
     /**
      * Allocate a new ConstLinearBlockBuffer wrapping around C2Buffer object.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   buffer  linear C2Buffer object to wrap around.
+     * \return          ConstLinearBlockBuffer object with readable mapping.
+     *                  nullptr if unsuccessful.
      */
     static sp<ConstLinearBlockBuffer> Allocate(
             const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer);
@@ -156,6 +167,110 @@
     std::shared_ptr<C2Buffer> mBufferRef;
 };
 
+/**
+ * MediaCodecBuffer implementation wraps around C2GraphicBlock.
+ *
+ * This object exposes the underlying bits via accessor APIs and "image-data"
+ * metadata, created automatically at allocation time.
+ */
+class GraphicBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new GraphicBlockBuffer wrapping around C2GraphicBlock object.
+     * If |block| is not in good color formats, it allocates YV12 local buffer
+     * and copies the content over at asC2Buffer().
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   block   C2GraphicBlock object to wrap around.
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          GraphicBlockBuffer object with writable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<GraphicBlockBuffer> Allocate(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2GraphicBlock> &block,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+
+    virtual ~GraphicBlockBuffer() = default;
+
+private:
+    GraphicBlockBuffer(
+            const sp<AMessage> &format,
+            const sp<ABuffer> &buffer,
+            C2GraphicView &&view,
+            const std::shared_ptr<C2GraphicBlock> &block,
+            const sp<ABuffer> &imageData,
+            bool wrapped);
+    GraphicBlockBuffer() = delete;
+
+    inline MediaImage2 *imageData() { return (MediaImage2 *)mImageData->data(); }
+
+    C2GraphicView mView;
+    std::shared_ptr<C2GraphicBlock> mBlock;
+    sp<ABuffer> mImageData;
+    const bool mWrapped;
+};
+
+/**
+ * MediaCodecBuffer implementation wraps around graphic C2Buffer object.
+ *
+ * This object exposes the underlying bits via accessor APIs and "image-data"
+ * metadata, created automatically at allocation time.
+ */
+class ConstGraphicBlockBuffer : public Codec2Buffer {
+public:
+    /**
+     * Allocate a new ConstGraphicBlockBuffer wrapping around C2Buffer object.
+     * If |buffer| is not in good color formats, it allocates YV12 local buffer
+     * and copies the content of |buffer| over to expose.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   buffer  graphic C2Buffer object to wrap around.
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          ConstGraphicBlockBuffer object with readable mapping.
+     *                  nullptr if unsuccessful.
+     */
+    static sp<ConstGraphicBlockBuffer> Allocate(
+            const sp<AMessage> &format,
+            const std::shared_ptr<C2Buffer> &buffer,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    /**
+     * Allocate a new ConstGraphicBlockBuffer which allocates YV12 local buffer
+     * and copies the content of |buffer| over to expose.
+     *
+     * \param   format  mandatory buffer format for MediaCodecBuffer
+     * \param   alloc   a function to allocate backing ABuffer if needed.
+     * \return          ConstGraphicBlockBuffer object with no wrapping buffer.
+     */
+    static sp<ConstGraphicBlockBuffer> AllocateEmpty(
+            const sp<AMessage> &format,
+            std::function<sp<ABuffer>(size_t)> alloc);
+
+    std::shared_ptr<C2Buffer> asC2Buffer() override;
+    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
+    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
+
+    virtual ~ConstGraphicBlockBuffer() = default;
+
+private:
+    ConstGraphicBlockBuffer(
+            const sp<AMessage> &format,
+            const sp<ABuffer> &aBuffer,
+            std::unique_ptr<const C2GraphicView> &&view,
+            const std::shared_ptr<C2Buffer> &buffer,
+            const sp<ABuffer> &imageData,
+            bool wrapped);
+    ConstGraphicBlockBuffer() = delete;
+
+    sp<ABuffer> mImageData;
+    std::unique_ptr<const C2GraphicView> mView;
+    std::shared_ptr<C2Buffer> mBufferRef;
+    const bool mWrapped;
+};
+
 }  // namespace android
 
 #endif  // CODEC2_BUFFER_H_
diff --git a/media/libstagefright/include/media/stagefright/CCodec.h b/media/libstagefright/include/media/stagefright/CCodec.h
index 3a2670d..078b03e 100644
--- a/media/libstagefright/include/media/stagefright/CCodec.h
+++ b/media/libstagefright/include/media/stagefright/CCodec.h
@@ -69,6 +69,8 @@
 private:
     typedef std::chrono::time_point<std::chrono::steady_clock> TimePoint;
 
+    status_t tryAndReportOnError(std::function<status_t()> job);
+
     void initiateStop();
     void initiateRelease(bool sendCallback = true);
 
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 0b7bd26..090d4e1 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -1493,7 +1493,9 @@
         const uint8_t *data, size_t size) {
     static const char kStartCode[] = "\x00\x00\x01";
 
-    if (size < 3) {
+    // per ISO/IEC 14496-2 6.2.1, a chunk has a 3-byte prefix + 1-byte start code
+    // we need at least <prefix><start><next prefix> to successfully scan
+    if (size < 3 + 1 + 3) {
         return -EAGAIN;
     }
 
@@ -1501,7 +1503,7 @@
         return -EAGAIN;
     }
 
-    size_t offset = 3;
+    size_t offset = 4;
     while (offset + 2 < size) {
         if (!memcmp(&data[offset], kStartCode, 3)) {
             return offset;
@@ -1552,6 +1554,9 @@
                     state = EXPECT_VISUAL_OBJECT_START;
                 } else {
                     discard = true;
+                    offset += chunkSize;
+                    ALOGW("b/74114680, advance to next chunk");
+                    android_errorWriteLog(0x534e4554, "74114680");
                 }
                 break;
             }
diff --git a/packages/MediaComponents/Android.mk b/packages/MediaComponents/Android.mk
index 22eea25..19e4b24 100644
--- a/packages/MediaComponents/Android.mk
+++ b/packages/MediaComponents/Android.mk
@@ -32,6 +32,7 @@
 
 # TODO: Use System SDK once public APIs are approved
 # LOCAL_SDK_VERSION := system_current
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
diff --git a/packages/MediaComponents/res/layout/media_controller.xml b/packages/MediaComponents/res/layout/media_controller.xml
index aafe8b0..8488c84 100644
--- a/packages/MediaComponents/res/layout/media_controller.xml
+++ b/packages/MediaComponents/res/layout/media_controller.xml
@@ -104,7 +104,7 @@
             <view class="com.android.support.mediarouter.app.MediaRouteButton"
                 android:id="@+id/cast"
                 android:layout_centerVertical="true"
-                android:visibility="visible"
+                android:visibility="gone"
                 style="@style/TitleBarButton" />
         </LinearLayout>
 
diff --git a/packages/MediaComponents/test/runtest.sh b/packages/MediaComponents/runcts.sh
similarity index 69%
rename from packages/MediaComponents/test/runtest.sh
rename to packages/MediaComponents/runcts.sh
index edce230..0cf0e44 100644
--- a/packages/MediaComponents/test/runtest.sh
+++ b/packages/MediaComponents/runcts.sh
@@ -13,13 +13,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Usage '. runtest.sh'
+# Usage '. runcts.sh'
 
-function _runtest_mediacomponent_usage() {
-  echo 'runtest-MediaComponents [option]: Run MediaComponents test'
+function _runtest_cts_mediacomponent_usage() {
+  echo 'runtest-cts-MediaComponents [option]: Build, flash device,'
+  echo '              and run subset of CtsMediaTestCases that MediaComponents covers.'
+  echo '          *Warning* This bypasses CTS setup (e.g. download media contents from server)'
+  echo '          For running CTS in official way, use atest or cts-tradefed '
   echo '     -h|--help: This help'
-  echo '     --skip: Skip build. Just rerun-tests.'
-  echo '     --min: Only rebuild test apk and updatable library.'
+  echo '     --skip: Skip build and flash. Just rerun-tests'
+  echo '     --min: Only rebuild tests and updatable library.'
   echo '     -s [device_id]: Specify a device name to run test against.'
   echo '                     You can define ${ADBHOST} instead.'
   echo '     -r [count]: Repeat tests for given count. It will stop when fails.'
@@ -27,15 +30,25 @@
   echo '     -t [test]: Only run the specific test. Can be either a class or a method.'
 }
 
-function runtest-MediaComponents() {
+function runtest-cts-MediaComponents() {
   # Edit here if you want to support other tests.
   # List up libs and apks in the media_api needed for tests, and place test target at the last.
   local TEST_PACKAGE_DIR=("frameworks/av/packages/MediaComponents/test")
-  local BUILD_TARGETS=("MediaComponents" "MediaComponentsTest")
-  local INSTALL_TARGETS=("MediaComponentsTest")
+  local TEST_PACKAGE=("android.media.cts")
+  local BUILD_TARGETS=("MediaComponents" "CtsMediaTestCases")
+  # Don't include MediaComponents -- if we simply install it, system server
+  # wouldn't use the installed one.
+  local INSTALL_TARGETS=("CtsMediaTestCases")
   local TEST_RUNNER="android.support.test.runner.AndroidJUnitRunner"
   local DEPENDENCIES=("mockito-target-minus-junit4" "android-support-test" "compatibility-device-util")
-
+  local DEFAULT_TEST_TARGET=""
+  DEFAULT_TEST_TARGET+="android.media.cts.MediaBrowser2Test"
+  DEFAULT_TEST_TARGET+=",android.media.cts.MediaController2Test"
+  DEFAULT_TEST_TARGET+=",android.media.cts.MediaMetadata2Test"
+  DEFAULT_TEST_TARGET+=",android.media.cts.MediaSession2Test"
+  DEFAULT_TEST_TARGET+=",android.media.cts.MediaSession2_PermissionTest"
+  DEFAULT_TEST_TARGET+=",android.media.cts.MediaSessionManager_MediaSession2Test"
+  DEFAULT_TEST_TARGET+=",android.media.cts.SessionToken2Test"
   if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
     echo "Needs to lunch a target first"
     return
@@ -47,12 +60,12 @@
     local OPTION_MIN="false"
     local OPTION_REPEAT_COUNT="1"
     local OPTION_IGNORE="false"
-    local OPTION_TEST_TARGET=""
+    local OPTION_TEST_TARGET="${DEFAULT_TEST_TARGET}"
     local adbhost_local
     while (( "$#" )); do
       case "${1}" in
         -h|--help)
-          _runtest_mediacomponent_usage
+          _runtest_cts_mediacomponent_usage
           return
           ;;
         --skip)
@@ -95,7 +108,7 @@
     fi
 
     local target_dir="${ANDROID_BUILD_TOP}/${TEST_PACKAGE_DIR}"
-    local TEST_PACKAGE=$(sed -n 's/^.*\bpackage\b="\([a-z0-9\.]*\)".*$/\1/p' ${target_dir}/AndroidManifest.xml)
+    #local TEST_PACKAGE=$(sed -n 's/^.*\bpackage\b="\([a-z0-9\.]*\)".*$/\1/p' ${target_dir}/AndroidManifest.xml)
 
     if [[ "${OPTION_SKIP}" != "true" ]]; then
       # Build dependencies if needed.
@@ -126,26 +139,34 @@
       fi
       m ${build_targets} -j || break
 
-      ${adb} root
-      ${adb} remount
-      ${adb} shell stop
-      ${adb} shell setprop log.tag.MediaSessionService DEBUG
-      ${adb} sync
-      ${adb} shell start
+      local device_build_type="$(${adb} shell getprop ro.build.type)"
+      if [[ "${device_build_type}" == "user" ]]; then
+        # User build. Cannot adb sync
+        ${adb} reboot bootloader
+        fastboot flashall
+      else
+        ${adb} root
+        local device_verity_mode="$(${adb} shell getprop ro.boot.veritymode)"
+        if [[ "${device_verity_mode}" != "disabled" ]]; then
+          ${adb} disable-verity
+          ${adb} reboot
+          ${adb} wait-for-device || break
+          ${adb} root
+        fi
+        ${adb} remount
+        ${adb} shell stop
+        ${adb} shell setprop log.tag.MediaSessionService DEBUG
+        ${adb} sync
+        ${adb} shell start
+      fi
       ${adb} wait-for-device || break
       # Ensure package manager is loaded.
+      # TODO(jaewan): Find better way to wait
       sleep 15
 
       # Install apks
       local install_failed="false"
       for target in ${INSTALL_TARGETS[@]}; do
-        echo "${target}"
-        local target_dir=$(mgrep -l -e '^LOCAL_PACKAGE_NAME.*'"${target}$")
-        if [[ -z ${target_dir} ]]; then
-          continue
-        fi
-        target_dir=$(dirname ${target_dir})
-        local package=$(sed -n 's/^.*\bpackage\b="\([a-z0-9\._]*\)".*$/\1/p' ${target_dir}/AndroidManifest.xml)
         local apk_path=$(find ${OUT}/system ${OUT}/data -name ${target}.apk)
         local apk_num=$(find ${OUT}/system ${OUT}/data -name ${target}.apk | wc -l)
         if [[ "${apk_num}" != "1" ]]; then
@@ -188,4 +209,4 @@
 }
 
 echo "Following functions are added to your environment:"
-_runtest_mediacomponent_usage
+_runtest_cts_mediacomponent_usage
diff --git a/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl b/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
index 34251fb..ef7120d 100644
--- a/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
+++ b/packages/MediaComponents/src/com/android/media/IMediaSession2.aidl
@@ -62,7 +62,7 @@
     //////////////////////////////////////////////////////////////////////////////////////////////
     // library service specific
     //////////////////////////////////////////////////////////////////////////////////////////////
-    void getBrowserRoot(IMediaSession2Callback caller, in Bundle rootHints);
+    void getLibraryRoot(IMediaSession2Callback caller, in Bundle rootHints);
     void getItem(IMediaSession2Callback caller, String mediaId);
     void getChildren(IMediaSession2Callback caller, String parentId, int page, int pageSize,
             in Bundle extras);
diff --git a/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java b/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
index 122ebe7..c909099 100644
--- a/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
@@ -54,7 +54,7 @@
         final IMediaSession2 binder = getSessionBinder();
         if (binder != null) {
             try {
-                binder.getBrowserRoot(getControllerStub(), rootHints);
+                binder.getLibraryRoot(getControllerStub(), rootHints);
             } catch (RemoteException e) {
                 // TODO(jaewan): Handle disconnect.
                 if (DEBUG) {
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
index dd23148..96fdda0 100644
--- a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
@@ -314,12 +314,12 @@
     }
 
     @Override
-    public void skipToPrevious_impl() {
+    public void skipToPreviousItem_impl() {
         sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM);
     }
 
     @Override
-    public void skipToNext_impl() {
+    public void skipToNextItem_impl() {
         sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM);
     }
 
@@ -651,7 +651,7 @@
     }
 
     @Override
-    public MediaItem2 getCurrentPlaylistItem_impl() {
+    public MediaItem2 getCurrentMediaItem_impl() {
         // TODO(jaewan): Implement
         return null;
     }
diff --git a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
index 6a6a385..b3512cc 100644
--- a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
@@ -68,12 +68,12 @@
     public static class MediaLibrarySessionImpl extends MediaSession2Impl
             implements MediaLibrarySessionProvider {
         public MediaLibrarySessionImpl(Context context,
-                MediaPlayerBase player, String id, MediaPlaylistAgent mplc,
+                MediaPlayerBase player, String id, MediaPlaylistAgent playlistAgent,
                 VolumeProvider2 volumeProvider,
                 PendingIntent sessionActivity, Executor callbackExecutor,
                 MediaLibrarySessionCallback callback) {
-            super(context, player, id, mplc, volumeProvider, sessionActivity, callbackExecutor,
-                    callback);
+            super(context, player, id, playlistAgent, volumeProvider, sessionActivity,
+                    callbackExecutor, callback);
             // Don't put any extra initialization here. Here's the reason.
             // System service will recognize this session inside of the super constructor and would
             // connect to this session assuming that initialization is finished. However, if any
@@ -141,7 +141,7 @@
 
         @Override
         public MediaLibrarySession build_impl() {
-            return new MediaLibrarySessionImpl(mContext, mPlayer, mId, mMplc,
+            return new MediaLibrarySessionImpl(mContext, mPlayer, mId, mPlaylistAgent,
                     mVolumeProvider, mSessionActivity, mCallbackExecutor, mCallback).getInstance();
         }
     }
@@ -154,8 +154,7 @@
         public LibraryRootImpl(Context context, LibraryRoot instance, String rootId,
                 Bundle extras) {
             if (rootId == null) {
-                throw new IllegalArgumentException("The root id in BrowserRoot cannot be null. " +
-                        "Use null for BrowserRoot instead.");
+                throw new IllegalArgumentException("rootId shouldn't be null.");
             }
             mInstance = instance;
             mRootId = rootId;
diff --git a/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java b/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
index 7b2ee32..333455d 100644
--- a/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
@@ -123,11 +123,17 @@
 
     @Override
     public boolean containsKey_impl(String key) {
+        if (key == null) {
+            throw new IllegalArgumentException("key shouldn't be null");
+        }
         return mBundle.containsKey(key);
     }
 
     @Override
     public CharSequence getText_impl(@TextKey String key) {
+        if (key == null) {
+            throw new IllegalArgumentException("key shouldn't be null");
+        }
         return mBundle.getCharSequence(key);
     }
 
@@ -138,6 +144,9 @@
 
     @Override
     public String getString_impl(@TextKey String key) {
+        if (key == null) {
+            throw new IllegalArgumentException("key shouldn't be null");
+        }
         CharSequence text = mBundle.getCharSequence(key);
         if (text != null) {
             return text.toString();
@@ -147,11 +156,17 @@
 
     @Override
     public long getLong_impl(@LongKey String key) {
+        if (key == null) {
+            throw new IllegalArgumentException("key shouldn't be null");
+        }
         return mBundle.getLong(key, 0);
     }
 
     @Override
     public Rating2 getRating_impl(@RatingKey String key) {
+        if (key == null) {
+            throw new IllegalArgumentException("key shouldn't be null");
+        }
         // TODO(jaewan): Add backward compatibility
         Rating2 rating = null;
         try {
@@ -165,11 +180,17 @@
 
     @Override
     public float getFloat_impl(@FloatKey String key) {
+        if (key == null) {
+            throw new IllegalArgumentException("key shouldn't be null");
+        }
         return mBundle.getFloat(key);
     }
 
     @Override
     public Bitmap getBitmap_impl(@BitmapKey String key) {
+        if (key == null) {
+            throw new IllegalArgumentException("key shouldn't be null");
+        }
         Bitmap bmp = null;
         try {
             bmp = mBundle.getParcelable(key);
@@ -221,7 +242,8 @@
             mBundle = new Bundle();
         }
 
-        public BuilderImpl(Context context, MediaMetadata2.Builder instance, MediaMetadata2 source) {
+        public BuilderImpl(Context context, MediaMetadata2.Builder instance,
+                MediaMetadata2 source) {
             if (source == null) {
                 throw new IllegalArgumentException("source shouldn't be null");
             }
@@ -248,6 +270,9 @@
 
         @Override
         public Builder putText_impl(@TextKey String key, CharSequence value) {
+            if (key == null) {
+                throw new IllegalArgumentException("key shouldn't be null");
+            }
             if (METADATA_KEYS_TYPE.containsKey(key)) {
                 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
                     throw new IllegalArgumentException("The " + key
@@ -260,6 +285,9 @@
 
         @Override
         public Builder putString_impl(@TextKey String key, String value) {
+            if (key == null) {
+                throw new IllegalArgumentException("key shouldn't be null");
+            }
             if (METADATA_KEYS_TYPE.containsKey(key)) {
                 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
                     throw new IllegalArgumentException("The " + key
@@ -272,6 +300,9 @@
 
         @Override
         public Builder putLong_impl(@LongKey String key, long value) {
+            if (key == null) {
+                throw new IllegalArgumentException("key shouldn't be null");
+            }
             if (METADATA_KEYS_TYPE.containsKey(key)) {
                 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_LONG) {
                     throw new IllegalArgumentException("The " + key
@@ -284,6 +315,9 @@
 
         @Override
         public Builder putRating_impl(@RatingKey String key, Rating2 value) {
+            if (key == null) {
+                throw new IllegalArgumentException("key shouldn't be null");
+            }
             if (METADATA_KEYS_TYPE.containsKey(key)) {
                 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_RATING) {
                     throw new IllegalArgumentException("The " + key
@@ -296,6 +330,9 @@
 
         @Override
         public Builder putBitmap_impl(@BitmapKey String key, Bitmap value) {
+            if (key == null) {
+                throw new IllegalArgumentException("key shouldn't be null");
+            }
             if (METADATA_KEYS_TYPE.containsKey(key)) {
                 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
                     throw new IllegalArgumentException("The " + key
@@ -308,6 +345,9 @@
 
         @Override
         public Builder putFloat_impl(@FloatKey String key, float value) {
+            if (key == null) {
+                throw new IllegalArgumentException("key shouldn't be null");
+            }
             if (METADATA_KEYS_TYPE.containsKey(key)) {
                 if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_FLOAT) {
                     throw new IllegalArgumentException("The " + key
@@ -329,7 +369,8 @@
             return new MediaMetadata2Impl(mContext, mBundle).getInstance();
         }
 
-        private Bitmap scaleBitmap(Bitmap bmp, int maxSize) { float maxSizeF = maxSize;
+        private Bitmap scaleBitmap(Bitmap bmp, int maxSize) {
+            float maxSizeF = maxSize;
             float widthScale = maxSizeF / bmp.getWidth();
             float heightScale = maxSizeF / bmp.getHeight();
             float scale = Math.min(widthScale, heightScale);
diff --git a/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java b/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java
new file mode 100644
index 0000000..bab29b7
--- /dev/null
+++ b/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.media;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.media.MediaItem2;
+import android.media.MediaMetadata2;
+import android.media.MediaPlaylistAgent;
+import android.media.MediaPlaylistAgent.PlaylistEventCallback;
+import android.media.update.MediaPlaylistAgentProvider;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public class MediaPlaylistAgentImpl implements MediaPlaylistAgentProvider {
+    private static final String TAG = "MediaPlaylistAgent";
+
+    private final Context mContext;
+    private final MediaPlaylistAgent mInstance;
+
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private final ArrayMap<PlaylistEventCallback, Executor> mCallbacks = new ArrayMap<>();
+
+    public MediaPlaylistAgentImpl(Context context, MediaPlaylistAgent instance) {
+        mContext = context;
+        mInstance = instance;
+    }
+
+    final public void registerPlaylistEventCallback_impl(
+            @NonNull @CallbackExecutor Executor executor, @NonNull PlaylistEventCallback callback) {
+        if (executor == null) {
+            throw new IllegalArgumentException("executor shouldn't be null");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("callback shouldn't be null");
+        }
+
+        synchronized (mLock) {
+            if (mCallbacks.get(callback) != null) {
+                Log.w(TAG, "callback is already added. Ignoring.");
+                return;
+            }
+            mCallbacks.put(callback, executor);
+        }
+    }
+
+    final public void unregisterPlaylistEventCallback_impl(
+            @NonNull PlaylistEventCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback shouldn't be null");
+        }
+        synchronized (mLock) {
+            mCallbacks.remove(callback);
+        }
+    }
+
+    final public void notifyPlaylistChanged_impl() {
+        ArrayMap<PlaylistEventCallback, Executor> callbacks = getCallbacks();
+        List<MediaItem2> playlist= mInstance.getPlaylist();
+        MediaMetadata2 metadata = mInstance.getPlaylistMetadata();
+        for (int i = 0; i < callbacks.size(); i++) {
+            final PlaylistEventCallback callback = callbacks.keyAt(i);
+            final Executor executor = callbacks.valueAt(i);
+            executor.execute(() -> callback.onPlaylistChanged(
+                    mInstance, playlist, metadata));
+        }
+    }
+
+    final public void notifyPlaylistMetadataChanged_impl() {
+        ArrayMap<PlaylistEventCallback, Executor> callbacks = getCallbacks();
+        for (int i = 0; i < callbacks.size(); i++) {
+            final PlaylistEventCallback callback = callbacks.keyAt(i);
+            final Executor executor = callbacks.valueAt(i);
+            executor.execute(() -> callback.onPlaylistMetadataChanged(
+                    mInstance, mInstance.getPlaylistMetadata()));
+        }
+    }
+
+    final public void notifyShuffleModeChanged_impl() {
+        ArrayMap<PlaylistEventCallback, Executor> callbacks = getCallbacks();
+        for (int i = 0; i < callbacks.size(); i++) {
+            final PlaylistEventCallback callback = callbacks.keyAt(i);
+            final Executor executor = callbacks.valueAt(i);
+            executor.execute(() -> callback.onShuffleModeChanged(
+                    mInstance, mInstance.getShuffleMode()));
+        }
+    }
+
+    final public void notifyRepeatModeChanged_impl() {
+        ArrayMap<PlaylistEventCallback, Executor> callbacks = getCallbacks();
+        for (int i = 0; i < callbacks.size(); i++) {
+            final PlaylistEventCallback callback = callbacks.keyAt(i);
+            final Executor executor = callbacks.valueAt(i);
+            executor.execute(() -> callback.onRepeatModeChanged(
+                    mInstance, mInstance.getRepeatMode()));
+        }
+    }
+
+    public @Nullable List<MediaItem2> getPlaylist_impl() {
+        // empty implementation
+        return null;
+    }
+
+    public void setPlaylist_impl(@NonNull List<MediaItem2> list,
+            @Nullable MediaMetadata2 metadata) {
+        // empty implementation
+    }
+
+    public @Nullable MediaMetadata2 getPlaylistMetadata_impl() {
+        // empty implementation
+        return null;
+    }
+
+    public void updatePlaylistMetadata_impl(@Nullable MediaMetadata2 metadata) {
+        // empty implementation
+    }
+
+    public void addPlaylistItem_impl(int index, @NonNull MediaItem2 item) {
+        // empty implementation
+    }
+
+    public void removePlaylistItem_impl(@NonNull MediaItem2 item) {
+        // empty implementation
+    }
+
+    public void replacePlaylistItem_impl(int index, @NonNull MediaItem2 item) {
+        // empty implementation
+    }
+
+    public void skipToPlaylistItem_impl(@NonNull MediaItem2 item) {
+        // empty implementation
+    }
+
+    public void skipToPreviousItem_impl() {
+        // empty implementation
+    }
+
+    public void skipToNextItem_impl() {
+        // empty implementation
+    }
+
+    public int getRepeatMode_impl() {
+        return MediaPlaylistAgent.REPEAT_MODE_NONE;
+    }
+
+    public void setRepeatMode_impl(int repeatMode) {
+        // empty implementation
+    }
+
+    public int getShuffleMode_impl() {
+        // empty implementation
+        return MediaPlaylistAgent.SHUFFLE_MODE_NONE;
+    }
+
+    public void setShuffleMode_impl(int shuffleMode) {
+        // empty implementation
+    }
+
+    private ArrayMap<PlaylistEventCallback, Executor> getCallbacks() {
+        ArrayMap<PlaylistEventCallback, Executor> callbacks = new ArrayMap<>();
+        synchronized (mLock) {
+            callbacks.putAll(mCallbacks);
+        }
+        return callbacks;
+    }
+}
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index 1f24d4e..5c18515 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -29,7 +29,9 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.media.AudioAttributes;
+import android.media.AudioFocusRequest;
 import android.media.AudioManager;
+import android.media.DataSourceDesc;
 import android.media.MediaController2;
 import android.media.MediaController2.PlaybackInfo;
 import android.media.MediaItem2;
@@ -38,6 +40,7 @@
 import android.media.MediaPlayerBase;
 import android.media.MediaPlayerBase.PlayerEventCallback;
 import android.media.MediaPlaylistAgent;
+import android.media.MediaPlaylistAgent.PlaylistEventCallback;
 import android.media.MediaSession2;
 import android.media.MediaSession2.Builder;
 import android.media.MediaSession2.Command;
@@ -85,6 +88,8 @@
     private final AudioManager mAudioManager;
     private final ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>();
     private final PendingIntent mSessionActivity;
+    private final PlayerEventCallback mPlayerEventCallback;
+    private final PlaylistEventCallback mPlaylistEventCallback;
 
     // mPlayer is set to null when the session is closed, and we shouldn't throw an exception
     // nor leave log always for using mPlayer when it's null. Here's the reason.
@@ -105,27 +110,25 @@
     @GuardedBy("mLock")
     private MediaPlayerBase mPlayer;
     @GuardedBy("mLock")
-    private MediaPlaylistAgent mMplc;
+    private MediaPlaylistAgent mPlaylistAgent;
     @GuardedBy("mLock")
     private VolumeProvider2 mVolumeProvider;
     @GuardedBy("mLock")
     private PlaybackInfo mPlaybackInfo;
-    @GuardedBy("mLock")
-    private MyEventCallback mEventCallback;
 
     /**
      * Can be only called by the {@link Builder#build()}.
      * @param context
      * @param player
      * @param id
-     * @param mplc
+     * @param playlistAgent
      * @param volumeProvider
      * @param sessionActivity
      * @param callbackExecutor
      * @param callback
      */
     public MediaSession2Impl(Context context, MediaPlayerBase player, String id,
-            MediaPlaylistAgent mplc, VolumeProvider2 volumeProvider,
+            MediaPlaylistAgent playlistAgent, VolumeProvider2 volumeProvider,
             PendingIntent sessionActivity,
             Executor callbackExecutor, SessionCallback callback) {
         // TODO(jaewan): Keep other params.
@@ -140,7 +143,8 @@
         mSessionActivity = sessionActivity;
         mSessionStub = new MediaSession2Stub(this);
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        mMplc = mplc;
+        mPlayerEventCallback = new MyPlayerEventCallback(this);
+        mPlaylistEventCallback = new MyPlaylistEventCallback(this);
 
         // Infer type from the id and package name.
         String libraryService = getServiceName(context, MediaLibraryService2.SERVICE_INTERFACE, id);
@@ -159,7 +163,7 @@
                     mContext.getPackageName(), null, id, mSessionStub).getInstance();
         }
 
-        setPlayer(player, volumeProvider);
+        updatePlayer(player, playlistAgent, volumeProvider);
 
         // Ask server for the sanity check, and starts
         // Sanity check for making session ID unique 'per package' cannot be done in here.
@@ -204,29 +208,49 @@
     }
 
     @Override
-    public void updatePlayer_impl(MediaPlayerBase player, MediaPlaylistAgent mplc,
+    public void updatePlayer_impl(MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
             VolumeProvider2 volumeProvider) throws IllegalArgumentException {
         ensureCallingThread();
         if (player == null) {
             throw new IllegalArgumentException("player shouldn't be null");
         }
-        mMplc = mplc;
-        setPlayer(player, volumeProvider);
+        updatePlayer(player, playlistAgent, volumeProvider);
     }
 
-    private void setPlayer(MediaPlayerBase player, VolumeProvider2 volumeProvider) {
+    private void updatePlayer(MediaPlayerBase player, MediaPlaylistAgent agent,
+            VolumeProvider2 volumeProvider) {
+        final MediaPlayerBase oldPlayer;
+        final MediaPlaylistAgent oldAgent;
         final PlaybackInfo info = createPlaybackInfo(volumeProvider, player.getAudioAttributes());
         synchronized (mLock) {
-            if (mPlayer != null && mEventCallback != null) {
-                // This might not work for a poorly implemented player.
-                mPlayer.unregisterPlayerEventCallback(mEventCallback);
-            }
+            oldPlayer = mPlayer;
+            oldAgent = mPlaylistAgent;
             mPlayer = player;
-            mEventCallback = new MyEventCallback(this, player);
-            player.registerPlayerEventCallback(mCallbackExecutor, mEventCallback);
+            // TODO(jaewan): Replace this with the proper default agent (b/74090741)
+            if (agent == null) {
+                agent = new MediaPlaylistAgent(mContext) {};
+            }
+            mPlaylistAgent = agent;
             mVolumeProvider = volumeProvider;
             mPlaybackInfo = info;
         }
+        if (player != oldPlayer) {
+            player.registerPlayerEventCallback(mCallbackExecutor, mPlayerEventCallback);
+            if (oldPlayer != null) {
+                // Warning: Poorly implement player may ignore this
+                oldPlayer.unregisterPlayerEventCallback(mPlayerEventCallback);
+            }
+        }
+        if (agent != oldAgent) {
+            agent.registerPlaylistEventCallback(mCallbackExecutor, mPlaylistEventCallback);
+            if (oldAgent != null) {
+                // Warning: Poorly implement player may ignore this
+                oldAgent.unregisterPlaylistEventCallback(mPlaylistEventCallback);
+            }
+        }
+        // TODO(jaewan): Notify controllers about the change in the media player base (b/74370608)
+        //               Note that notification will be done indirectly by telling player state,
+        //               position, buffered position, etc.
         mSessionStub.notifyPlaybackInfoChanged(info);
         notifyPlaybackStateChangedNotLocked(mInstance.getPlaybackState());
     }
@@ -281,12 +305,19 @@
             // Invalidate previously published session stub.
             mSessionStub.destroyNotLocked();
         }
+        final MediaPlayerBase player;
+        final MediaPlaylistAgent agent;
         synchronized (mLock) {
-            if (mPlayer != null) {
-                // close can be called multiple times
-                mPlayer.unregisterPlayerEventCallback(mEventCallback);
-                mPlayer = null;
-            }
+            player = mPlayer;
+            mPlayer = null;
+            agent = mPlaylistAgent;
+            mPlaylistAgent = null;
+        }
+        if (player != null) {
+            player.unregisterPlayerEventCallback(mPlayerEventCallback);
+        }
+        if (agent != null) {
+            agent.unregisterPlaylistEventCallback(mPlaylistEventCallback);
         }
     }
 
@@ -296,6 +327,11 @@
     }
 
     @Override
+    public MediaPlaylistAgent getPlaylistAgent_impl() {
+        return mPlaylistAgent;
+    }
+
+    @Override
     public VolumeProvider2 getVolumeProvider_impl() {
         return mVolumeProvider;
     }
@@ -311,7 +347,7 @@
     }
 
     @Override
-    public void setAudioFocusRequest_impl(int focusGain) {
+    public void setAudioFocusRequest_impl(AudioFocusRequest afr) {
         // implement
     }
 
@@ -342,18 +378,16 @@
         ensureCallingThread();
         final MediaPlayerBase player = mPlayer;
         if (player != null) {
-            // TODO: Uncomment or remove
-            //player.stop();
-            player.pause();
+            player.reset();
         } else if (DEBUG) {
             Log.d(TAG, "API calls after the close()", new IllegalStateException());
         }
     }
 
     @Override
-    public void skipToPrevious_impl() {
+    public void skipToPreviousItem_impl() {
         ensureCallingThread();
-        // TODO: Uncomment or remove
+        // TODO(jaewan): Implement this (b/74175632)
         /*
         final MediaPlayerBase player = mPlayer;
         if (player != null) {
@@ -366,14 +400,17 @@
     }
 
     @Override
-    public void skipToNext_impl() {
+    public void skipToNextItem_impl() {
         ensureCallingThread();
+        // TODO(jaewan): Implement this (b/74175632)
+        /*
         final MediaPlayerBase player = mPlayer;
         if (player != null) {
             player.skipToNext();
         } else if (DEBUG) {
             Log.d(TAG, "API calls after the close()", new IllegalStateException());
         }
+        */
     }
 
     @Override
@@ -441,11 +478,20 @@
     @Override
     public void sendCustomCommand_impl(ControllerInfo controller, Command command, Bundle args,
             ResultReceiver receiver) {
+        if (controller == null) {
+            throw new IllegalArgumentException("controller shouldn't be null");
+        }
+        if (command == null) {
+            throw new IllegalArgumentException("command shouldn't be null");
+        }
         mSessionStub.sendCustomCommand(controller, command, args, receiver);
     }
 
     @Override
     public void sendCustomCommand_impl(Command command, Bundle args) {
+        if (command == null) {
+            throw new IllegalArgumentException("command shouldn't be null");
+        }
         mSessionStub.sendCustomCommand(command, args);
     }
 
@@ -459,7 +505,7 @@
         /*
         final MediaPlayerBase player = mPlayer;
         if (player != null) {
-            // TODO implement, use the SessionPlaylistController itf
+            // TODO implement and use SessionPlaylistAgent
             //player.setPlaylist(playlist);
             mSessionStub.notifyPlaylistChanged(playlist);
         } else if (DEBUG) {
@@ -470,21 +516,39 @@
 
     @Override
     public void addPlaylistItem_impl(int index, MediaItem2 item) {
+        if (index < 0) {
+            throw new IllegalArgumentException("index shouldn't be negative");
+        }
+        if (item == null) {
+            throw new IllegalArgumentException("item shouldn't be null");
+        }
         // TODO(jaewan): Implement
     }
 
     @Override
     public void removePlaylistItem_impl(MediaItem2 item) {
+        if (item == null) {
+            throw new IllegalArgumentException("item shouldn't be null");
+        }
         // TODO(jaewan): Implement
     }
 
     @Override
     public void editPlaylistItem_impl(MediaItem2 item) {
+        if (item == null) {
+            throw new IllegalArgumentException("item shouldn't be null");
+        }
         // TODO(jaewan): Implement
     }
 
     @Override
     public void replacePlaylistItem_impl(int index, MediaItem2 item) {
+        if (index < 0) {
+            throw new IllegalArgumentException("index shouldn't be negative");
+        }
+        if (item == null) {
+            throw new IllegalArgumentException("item shouldn't be null");
+        }
         // TODO(jaewan): Implement
     }
 
@@ -567,6 +631,9 @@
     @Override
     public void skipToPlaylistItem_impl(MediaItem2 item) {
         ensureCallingThread();
+        if (item == null) {
+            throw new IllegalArgumentException("item shouldn't be null");
+        }
         // TODO: Uncomment or remove
         /*
         final MediaPlayerBase player = mPlayer;
@@ -727,51 +794,70 @@
         return mSessionActivity;
     }
 
-    private static class MyEventCallback extends PlayerEventCallback {
+    private static class MyPlayerEventCallback extends PlayerEventCallback {
         private final WeakReference<MediaSession2Impl> mSession;
-        private final MediaPlayerBase mPlayer;
 
-        private MyEventCallback(MediaSession2Impl session, MediaPlayerBase player) {
+        private MyPlayerEventCallback(MediaSession2Impl session) {
             mSession = new WeakReference<>(session);
-            mPlayer = player;
         }
 
-        // TODO: Uncomment or remove
-        /*
         @Override
-        public void onPlaybackStateChanged(PlaybackState2 state) {
-            MediaSession2Impl session = mSession.get();
-            if (mPlayer != session.mInstance.getPlayer()) {
-                Log.w(TAG, "Unexpected playback state change notifications. Ignoring.",
-                        new IllegalStateException());
-                return;
-            }
-            if (DEBUG) {
-                Log.d(TAG, "onPlaybackStateChanged from player, state=" + state);
-            }
-            session.notifyPlaybackStateChangedNotLocked(state);
+        public void onCurrentDataSourceChanged(MediaPlayerBase mpb, DataSourceDesc dsd) {
+            super.onCurrentDataSourceChanged(mpb, dsd);
+            // TODO(jaewan): Handle this b/74370608
         }
-        */
 
-        // TODO: Uncomment or remove
-        /*
         @Override
-        public void onError(String mediaId, int what, int extra) {
-            MediaSession2Impl session = mSession.get();
-            if (mPlayer != session.mInstance.getPlayer()) {
-                Log.w(TAG, "Unexpected playback state change notifications. Ignoring.",
-                        new IllegalStateException());
-                return;
-            }
-            if (DEBUG) {
-                Log.d(TAG, "onError from player, mediaId=" + mediaId + ", what=" + what
-                        + ", extra=" + extra);
-            }
-            session.notifyErrorNotLocked(mediaId, what, extra);
+        public void onMediaPrepared(MediaPlayerBase mpb, DataSourceDesc dsd) {
+            super.onMediaPrepared(mpb, dsd);
+            // TODO(jaewan): Handle this b/74370608
         }
-        */
 
-        //TODO implement the real PlayerEventCallback methods
+        @Override
+        public void onPlayerStateChanged(MediaPlayerBase mpb, int state) {
+            super.onPlayerStateChanged(mpb, state);
+            // TODO(jaewan): Handle this b/74370608
+        }
+
+        @Override
+        public void onBufferingStateChanged(MediaPlayerBase mpb, DataSourceDesc dsd, int state) {
+            super.onBufferingStateChanged(mpb, dsd, state);
+            // TODO(jaewan): Handle this b/74370608
+        }
+    }
+
+    private static class MyPlaylistEventCallback extends PlaylistEventCallback {
+        private final WeakReference<MediaSession2Impl> mSession;
+
+        private MyPlaylistEventCallback(MediaSession2Impl session) {
+            mSession = new WeakReference<>(session);
+        }
+
+        @Override
+        public void onPlaylistChanged(MediaPlaylistAgent playlistAgent, List<MediaItem2> list,
+                MediaMetadata2 metadata) {
+            super.onPlaylistChanged(playlistAgent, list, metadata);
+            // TODO(jaewan): Handle this (b/74326040)
+        }
+
+        @Override
+        public void onPlaylistMetadataChanged(MediaPlaylistAgent playlistAgent,
+                MediaMetadata2 metadata) {
+            super.onPlaylistMetadataChanged(playlistAgent, metadata);
+            // TODO(jaewan): Handle this (b/74174649)
+        }
+
+        @Override
+        public void onShuffleModeChanged(MediaPlaylistAgent playlistAgent, int shuffleMode) {
+            super.onShuffleModeChanged(playlistAgent, shuffleMode);
+            // TODO(jaewan): Handle this (b/74118768)
+        }
+
+        @Override
+        public void onRepeatModeChanged(MediaPlaylistAgent playlistAgent, int repeatMode) {
+            super.onRepeatModeChanged(playlistAgent, repeatMode);
+            // TODO(jaewan): Handle this (b/74118768)
+        }
     }
 
     public static final class CommandImpl implements CommandProvider {
@@ -832,6 +918,9 @@
          * @return a new Command instance from the Bundle
          */
         public static Command fromBundle_impl(Context context, Bundle command) {
+            if (command == null) {
+                throw new IllegalArgumentException("command shouldn't be null");
+            }
             int code = command.getInt(KEY_COMMAND_CODE);
             if (code != COMMAND_CODE_CUSTOM) {
                 return new Command(context, code);
@@ -884,6 +973,9 @@
 
         @Override
         public void addCommand_impl(Command command) {
+            if (command == null) {
+                throw new IllegalArgumentException("command shouldn't be null");
+            }
             mCommands.add(command);
         }
 
@@ -896,11 +988,17 @@
 
         @Override
         public void removeCommand_impl(Command command) {
+            if (command == null) {
+                throw new IllegalArgumentException("command shouldn't be null");
+            }
             mCommands.remove(command);
         }
 
         @Override
         public boolean hasCommand_impl(Command command) {
+            if (command == null) {
+                throw new IllegalArgumentException("command shouldn't be null");
+            }
             return mCommands.contains(command);
         }
 
@@ -974,6 +1072,13 @@
 
         public ControllerInfoImpl(Context context, ControllerInfo instance, int uid,
                 int pid, String packageName, IMediaSession2Callback callback) {
+            if (TextUtils.isEmpty(packageName)) {
+                throw new IllegalArgumentException("packageName shouldn't be empty");
+            }
+            if (callback == null) {
+                throw new IllegalArgumentException("callback shouldn't be null");
+            }
+
             mInstance = instance;
             mUid = uid;
             mPackageName = packageName;
@@ -1275,7 +1380,7 @@
         String mId;
         Executor mCallbackExecutor;
         C mCallback;
-        MediaPlaylistAgent mMplc;
+        MediaPlaylistAgent mPlaylistAgent;
         VolumeProvider2 mVolumeProvider;
         PendingIntent mSessionActivity;
 
@@ -1296,6 +1401,7 @@
             mId = "";
         }
 
+        @Override
         public void setPlayer_impl(MediaPlayerBase player) {
             if (player == null) {
                 throw new IllegalArgumentException("player shouldn't be null");
@@ -1304,24 +1410,24 @@
         }
 
         @Override
-        public void setPlaylistController_impl(MediaPlaylistAgent mplc) {
-            if (mplc == null) {
-                throw new IllegalArgumentException("mplc shouldn't be null");
+        public void setPlaylistAgent_impl(MediaPlaylistAgent playlistAgent) {
+            if (playlistAgent == null) {
+                throw new IllegalArgumentException("playlistAgent shouldn't be null");
             }
-            mMplc = mplc;
+            mPlaylistAgent = playlistAgent;
         }
 
+        @Override
         public void setVolumeProvider_impl(VolumeProvider2 volumeProvider) {
-            if (volumeProvider == null) {
-                throw new IllegalArgumentException("volumeProvider shouldn't be null");
-            }
             mVolumeProvider = volumeProvider;
         }
 
+        @Override
         public void setSessionActivity_impl(PendingIntent pi) {
             mSessionActivity = pi;
         }
 
+        @Override
         public void setId_impl(String id) {
             if (id == null) {
                 throw new IllegalArgumentException("id shouldn't be null");
@@ -1329,6 +1435,7 @@
             mId = id;
         }
 
+        @Override
         public void setSessionCallback_impl(Executor executor, C callback) {
             if (executor == null) {
                 throw new IllegalArgumentException("executor shouldn't be null");
@@ -1340,6 +1447,7 @@
             mCallback = callback;
         }
 
+        @Override
         public abstract T build_impl();
     }
 
@@ -1356,8 +1464,7 @@
             if (mCallback == null) {
                 mCallback = new SessionCallback(mContext) {};
             }
-
-            return new MediaSession2Impl(mContext, mPlayer, mId, mMplc,
+            return new MediaSession2Impl(mContext, mPlayer, mId, mPlaylistAgent,
                     mVolumeProvider, mSessionActivity, mCallbackExecutor, mCallback).getInstance();
         }
     }
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
index d4164f6..a9c5224 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
@@ -481,6 +481,11 @@
             return;
         }
         final Command command = Command.fromBundle(session.getContext(), commandBundle);
+        if (command == null) {
+            Log.w(TAG, "sendCustomCommand(): Ignoring null command from "
+                    + getControllerIfAble(caller));
+            return;
+        }
         final ControllerInfo controller = getControllerIfAble(caller, command);
         if (controller == null) {
             return;
@@ -503,6 +508,10 @@
         if (session == null || controller == null) {
             return;
         }
+        if (uri == null) {
+            Log.w(TAG, "prepareFromUri(): Ignoring null uri from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(
                     caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_URI) == null) {
@@ -522,6 +531,10 @@
         if (session == null || controller == null) {
             return;
         }
+        if (TextUtils.isEmpty(query)) {
+            Log.w(TAG, "prepareFromSearch(): Ignoring empty query from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(
                     caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_SEARCH) == null) {
@@ -541,6 +554,10 @@
         if (session == null || controller == null) {
             return;
         }
+        if (mediaId == null) {
+            Log.w(TAG, "prepareFromMediaId(): Ignoring null mediaId from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(
                     caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_MEDIA_ID) == null) {
@@ -560,6 +577,10 @@
         if (session == null || controller == null) {
             return;
         }
+        if (uri == null) {
+            Log.w(TAG, "playFromUri(): Ignoring null uri from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(
                     caller, MediaSession2.COMMAND_CODE_PLAY_FROM_URI) == null) {
@@ -578,6 +599,10 @@
         if (session == null || controller == null) {
             return;
         }
+        if (TextUtils.isEmpty(query)) {
+            Log.w(TAG, "playFromSearch(): Ignoring empty query from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(
                     caller, MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH) == null) {
@@ -597,6 +622,10 @@
         if (session == null || controller == null) {
             return;
         }
+        if (mediaId == null) {
+            Log.w(TAG, "playFromMediaId(): Ignoring null mediaId from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (session == null) {
                 return;
@@ -617,14 +646,17 @@
             }
             return;
         }
+        Rating2 rating = Rating2Impl.fromBundle(sessionImpl.getContext(), ratingBundle);
+        if (rating == null) {
+            Log.w(TAG, "setRating(): Ignore null rating");
+            return;
+        }
         sessionImpl.getCallbackExecutor().execute(() -> {
             final MediaSession2Impl session = mSession.get();
             if (session == null) {
                 return;
             }
-            Rating2 rating = Rating2Impl.fromBundle(session.getContext(), ratingBundle);
-            session.getCallback().onSetRating(session.getInstance(),
-                    controller, mediaId, rating);
+            session.getCallback().onSetRating(session.getInstance(), controller, mediaId, rating);
         });
     }
 
@@ -633,7 +665,7 @@
     //////////////////////////////////////////////////////////////////////////////////////////////
 
     @Override
-    public void getBrowserRoot(final IMediaSession2Callback caller, final Bundle rootHints)
+    public void getLibraryRoot(final IMediaSession2Callback caller, final Bundle rootHints)
             throws RuntimeException {
         final MediaLibrarySessionImpl session = getLibrarySession();
         final ControllerInfo controller = getControllerIfAble(
@@ -744,36 +776,36 @@
         if (session == null || controller == null) {
             return;
         }
+        if (TextUtils.isEmpty(query)) {
+            Log.w(TAG, "search(): Ignoring empty query from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
                 return;
             }
-            session.getCallback().onSearch(session.getInstance(),
-                    controller, query, extras);
+            session.getCallback().onSearch(session.getInstance(), controller, query, extras);
         });
     }
 
     @Override
     public void getSearchResult(final IMediaSession2Callback caller, final String query,
             final int page, final int pageSize, final Bundle extras) {
-        if (TextUtils.isEmpty(query)) {
-            if (DEBUG) {
-                Log.d(TAG, "query shouldn't be empty");
-            }
-            return;
-        }
-        if (page < 1 || pageSize < 1) {
-            if (DEBUG) {
-                Log.d(TAG, "Neither page nor pageSize should be less than 1");
-            }
-            return;
-        }
         final MediaLibrarySessionImpl session = getLibrarySession();
         final ControllerInfo controller = getControllerIfAble(
                 caller, MediaSession2.COMMAND_CODE_BROWSER);
         if (session == null || controller == null) {
             return;
         }
+        if (TextUtils.isEmpty(query)) {
+            Log.w(TAG, "getSearchResult(): Ignoring empty query from " + controller);
+            return;
+        }
+        if (page < 1 || pageSize < 1) {
+            Log.w(TAG, "getSearchResult(): Ignoring negative page / pageSize."
+                    + " page=" + page + " pageSize=" + pageSize + " from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
                 return;
@@ -811,6 +843,10 @@
         if (session == null || controller == null) {
             return;
         }
+        if (parentId == null) {
+            Log.w(TAG, "subscribe(): Ignoring null parentId from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
                 return;
@@ -836,6 +872,10 @@
         if (session == null || controller == null) {
             return;
         }
+        if (parentId == null) {
+            Log.w(TAG, "unsubscribe(): Ignoring null parentId from " + controller);
+            return;
+        }
         session.getCallbackExecutor().execute(() -> {
             if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
                 return;
diff --git a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
index 4537d5f..6bd2b2a 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
@@ -138,7 +138,7 @@
 
     private class SessionServiceEventCallback extends PlayerEventCallback {
         @Override
-        public void onPlayerStateChanged(MediaPlayerBase mpb, int state) {
+        public void onPlayerStateChanged(MediaPlayerBase player, int state) {
             // TODO: Implement this
             return;
         }
diff --git a/packages/MediaComponents/src/com/android/media/RoutePlayer.java b/packages/MediaComponents/src/com/android/media/RoutePlayer.java
new file mode 100644
index 0000000..9450d34
--- /dev/null
+++ b/packages/MediaComponents/src/com/android/media/RoutePlayer.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.media;
+
+import android.content.Context;
+import android.media.DataSourceDesc;
+import android.media.session.MediaSession;
+import android.media.session.PlaybackState;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.RequiresApi;
+
+import com.android.support.mediarouter.media.MediaItemStatus;
+import com.android.support.mediarouter.media.MediaRouter;
+import com.android.support.mediarouter.media.MediaSessionStatus;
+import com.android.support.mediarouter.media.RemotePlaybackClient;
+import com.android.support.mediarouter.media.RemotePlaybackClient.ItemActionCallback;
+import com.android.support.mediarouter.media.RemotePlaybackClient.SessionActionCallback;
+import com.android.support.mediarouter.media.RemotePlaybackClient.StatusCallback;
+
+import java.util.Map;
+
+@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+public class RoutePlayer extends MediaSession.Callback {
+    public static final long PLAYBACK_ACTIONS = PlaybackState.ACTION_PAUSE
+            | PlaybackState.ACTION_PLAY | PlaybackState.ACTION_SEEK_TO
+            | PlaybackState.ACTION_FAST_FORWARD | PlaybackState.ACTION_REWIND;
+
+    private RemotePlaybackClient mClient;
+    private String mSessionId;
+    private String mItemId;
+    private PlayerEventCallback mCallback;
+
+    private StatusCallback mStatusCallback = new StatusCallback() {
+        @Override
+        public void onItemStatusChanged(Bundle data,
+                String sessionId, MediaSessionStatus sessionStatus,
+                String itemId, MediaItemStatus itemStatus) {
+            updateSessionStatus(sessionId, sessionStatus);
+            updateItemStatus(itemId, itemStatus);
+        }
+    };
+
+    public RoutePlayer(Context context, MediaRouter.RouteInfo route) {
+        mClient = new RemotePlaybackClient(context, route);
+        mClient.setStatusCallback(mStatusCallback);
+        mClient.startSession(null, new SessionActionCallback() {
+            @Override
+            public void onResult(Bundle data,
+                    String sessionId, MediaSessionStatus sessionStatus) {
+                updateSessionStatus(sessionId, sessionStatus);
+            }
+        });
+    }
+
+    @Override
+    public void onPlay() {
+        mClient.resume(null, new SessionActionCallback() {
+            @Override
+            public void onResult(Bundle data,
+                    String sessionId, MediaSessionStatus sessionStatus) {
+                updateSessionStatus(sessionId, sessionStatus);
+            }
+        });
+    }
+
+    @Override
+    public void onPause() {
+        mClient.pause(null, new SessionActionCallback() {
+            @Override
+            public void onResult(Bundle data,
+                    String sessionId, MediaSessionStatus sessionStatus) {
+                updateSessionStatus(sessionId, sessionStatus);
+            }
+        });
+    }
+
+    @Override
+    public void onSeekTo(long pos) {
+        mClient.seek(mItemId, pos, null, new ItemActionCallback() {
+            @Override
+            public void onResult(Bundle data,
+                    String sessionId, MediaSessionStatus sessionStatus,
+                    String itemId, MediaItemStatus itemStatus) {
+                updateSessionStatus(sessionId, sessionStatus);
+                updateItemStatus(itemId, itemStatus);
+            }
+        });
+    }
+
+    @Override
+    public void onStop() {
+        mClient.stop(null, new SessionActionCallback() {
+            @Override
+            public void onResult(Bundle data,
+                    String sessionId, MediaSessionStatus sessionStatus) {
+                updateSessionStatus(sessionId, sessionStatus);
+            }
+        });
+    }
+
+    public void setPlayerEventCallback(PlayerEventCallback callback) {
+        mCallback = callback;
+    }
+
+    public void openVideo(DataSourceDesc dsd) {
+        mClient.play(dsd.getUri(), "video/mp4", null, 0, null, new ItemActionCallback() {
+            @Override
+            public void onResult(Bundle data,
+                    String sessionId, MediaSessionStatus sessionStatus,
+                    String itemId, MediaItemStatus itemStatus) {
+                updateSessionStatus(sessionId, sessionStatus);
+                updateItemStatus(itemId, itemStatus);
+                playInternal(dsd.getUri());
+            }
+        });
+    }
+
+    public void release() {
+        if (mClient != null) {
+            mClient.release();
+            mClient = null;
+        }
+        if (mCallback != null) {
+            mCallback = null;
+        }
+    }
+
+    private void playInternal(Uri uri) {
+        mClient.play(uri, "video/mp4", null, 0, null, new ItemActionCallback() {
+            @Override
+            public void onResult(Bundle data,
+                    String sessionId, MediaSessionStatus sessionStatus,
+                    String itemId, MediaItemStatus itemStatus) {
+                updateSessionStatus(sessionId, sessionStatus);
+                updateItemStatus(itemId, itemStatus);
+            }
+        });
+    }
+
+    private void updateSessionStatus(String sessionId, MediaSessionStatus sessionStatus) {
+        mSessionId = sessionId;
+    }
+
+    private void updateItemStatus(String itemId, MediaItemStatus itemStatus) {
+        mItemId = itemId;
+        if (itemStatus == null || mCallback == null) return;
+        mCallback.onPlayerStateChanged(itemStatus);
+    }
+
+    public static abstract class PlayerEventCallback {
+        public void onPlayerStateChanged(MediaItemStatus itemStatus) { }
+    }
+}
diff --git a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
index 3965ccb..723622e 100644
--- a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
@@ -59,10 +59,10 @@
     public SessionToken2Impl(Context context, SessionToken2 instance,
             String packageName, String serviceName, int uid) {
         if (TextUtils.isEmpty(packageName)) {
-            throw new IllegalArgumentException("package name shouldn't be null");
+            throw new IllegalArgumentException("packageName shouldn't be empty");
         }
         if (TextUtils.isEmpty(serviceName)) {
-            throw new IllegalArgumentException("service name shouldn't be null");
+            throw new IllegalArgumentException("serviceName shouldn't be empty");
         }
         mInstance = instance;
         // Calculate uid if it's not specified.
diff --git a/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java b/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
index 5af3ddf..156bcae 100644
--- a/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
@@ -15,6 +15,10 @@
  */
 package com.android.media;
 
+import static android.media.VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
+import static android.media.VolumeProvider2.VOLUME_CONTROL_FIXED;
+import static android.media.VolumeProvider2.VOLUME_CONTROL_RELATIVE;
+
 import android.content.Context;
 import android.media.VolumeProvider2;
 import android.media.update.VolumeProvider2Provider;
@@ -31,6 +35,18 @@
 
     public VolumeProvider2Impl(Context context, VolumeProvider2 instance,
             @VolumeProvider2.ControlType int controlType, int maxVolume, int currentVolume) {
+        if (controlType != VOLUME_CONTROL_FIXED && controlType != VOLUME_CONTROL_RELATIVE
+                && controlType != VOLUME_CONTROL_ABSOLUTE) {
+            throw new IllegalArgumentException("wrong controlType " + controlType);
+        }
+        if (maxVolume < 0 || currentVolume < 0) {
+            throw new IllegalArgumentException("volume shouldn't be negative"
+                    + ", maxVolume=" + maxVolume + ", currentVolume=" + currentVolume);
+        }
+        if (currentVolume > maxVolume) {
+            throw new IllegalArgumentException("currentVolume shouldn't be greater than maxVolume"
+                    + ", maxVolume=" + maxVolume + ", currentVolume=" + currentVolume);
+        }
         mContext = context;
         mInstance = instance;
         mControlType = controlType;
@@ -55,6 +71,10 @@
 
     @Override
     public void setCurrentVolume_impl(int currentVolume) {
+        if (currentVolume < 0) {
+            throw new IllegalArgumentException("currentVolume shouldn't be negative"
+                    + ", currentVolume=" + currentVolume);
+        }
         mCurrentVolume = currentVolume;
         if (mCallback != null) {
             mCallback.onVolumeChanged(mInstance);
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
index 9a01ade..07b8788 100644
--- a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
+++ b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
@@ -32,6 +32,7 @@
 import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
 import android.media.MediaMetadata2;
 import android.media.MediaPlayerBase;
+import android.media.MediaPlaylistAgent;
 import android.media.MediaSession2;
 import android.media.MediaSession2.Command;
 import android.media.MediaSession2.CommandGroup;
@@ -50,6 +51,7 @@
 import android.media.update.MediaItem2Provider;
 import android.media.update.MediaLibraryService2Provider.LibraryRootProvider;
 import android.media.update.MediaMetadata2Provider;
+import android.media.update.MediaPlaylistAgentProvider;
 import android.media.update.MediaSession2Provider;
 import android.media.update.MediaSession2Provider.BuilderBaseProvider;
 import android.media.update.MediaSession2Provider.CommandButtonProvider.BuilderProvider;
@@ -76,6 +78,7 @@
 import com.android.media.MediaLibraryService2Impl;
 import com.android.media.MediaLibraryService2Impl.LibraryRootImpl;
 import com.android.media.MediaMetadata2Impl;
+import com.android.media.MediaPlaylistAgentImpl;
 import com.android.media.MediaSession2Impl;
 import com.android.media.MediaSession2Impl.PlaylistParamsImpl;
 import com.android.media.MediaSessionService2Impl;
@@ -301,4 +304,10 @@
     public PlaybackState2 fromBundle_PlaybackState2(Context context, Bundle bundle) {
         return PlaybackState2Impl.fromBundle(context, bundle);
     }
+
+    @Override
+    public MediaPlaylistAgentProvider createMediaPlaylistAgent(Context context,
+            MediaPlaylistAgent instance) {
+        return new MediaPlaylistAgentImpl(context, instance);
+    }
 }
diff --git a/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java b/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java
index 8577123..fc92e85 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java
@@ -18,7 +18,7 @@
 
 import android.content.Context;
 import android.graphics.Rect;
-import android.media.MediaPlayer;
+import android.media.MediaPlayer2;
 import android.support.annotation.NonNull;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -33,7 +33,7 @@
     private static final boolean DEBUG = true; // STOPSHIP: Log.isLoggable(TAG, Log.DEBUG);
     private SurfaceHolder mSurfaceHolder = null;
     private SurfaceListener mSurfaceListener = null;
-    private MediaPlayer mMediaPlayer;
+    private MediaPlayer2 mMediaPlayer;
     // A flag to indicate taking over other view should be proceed.
     private boolean mIsTakingOverOldView;
     private VideoViewInterface mOldView;
@@ -62,7 +62,7 @@
     ////////////////////////////////////////////////////
 
     @Override
-    public boolean assignSurfaceToMediaPlayer(MediaPlayer mp) {
+    public boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp) {
         Log.d(TAG, "assignSurfaceToMediaPlayer(): mSurfaceHolder: " + mSurfaceHolder);
         if (mp == null || !hasAvailableSurface()) {
             return false;
@@ -82,7 +82,7 @@
     }
 
     @Override
-    public void setMediaPlayer(MediaPlayer mp) {
+    public void setMediaPlayer(MediaPlayer2 mp) {
         mMediaPlayer = mp;
         if (mIsTakingOverOldView) {
             takeOver(mOldView);
diff --git a/packages/MediaComponents/src/com/android/widget/VideoTextureView.java b/packages/MediaComponents/src/com/android/widget/VideoTextureView.java
index 69a4ebe..024a3aa 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoTextureView.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoTextureView.java
@@ -18,7 +18,7 @@
 
 import android.content.Context;
 import android.graphics.SurfaceTexture;
-import android.media.MediaPlayer;
+import android.media.MediaPlayer2;
 import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
 import android.util.AttributeSet;
@@ -38,7 +38,7 @@
     private SurfaceTexture mSurfaceTexture;
     private Surface mSurface;
     private SurfaceListener mSurfaceListener;
-    private MediaPlayer mMediaPlayer;
+    private MediaPlayer2 mMediaPlayer;
     // A flag to indicate taking over other view should be proceed.
     private boolean mIsTakingOverOldView;
     private VideoViewInterface mOldView;
@@ -66,7 +66,7 @@
     ////////////////////////////////////////////////////
 
     @Override
-    public boolean assignSurfaceToMediaPlayer(MediaPlayer mp) {
+    public boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp) {
         Log.d(TAG, "assignSurfaceToMediaPlayer(): mSurfaceTexture: " + mSurfaceTexture);
         if (mp == null || !hasAvailableSurface()) {
             // Surface is not ready.
@@ -87,7 +87,7 @@
     }
 
     @Override
-    public void setMediaPlayer(MediaPlayer mp) {
+    public void setMediaPlayer(MediaPlayer2 mp) {
         mMediaPlayer = mp;
         if (mIsTakingOverOldView) {
             takeOver(mOldView);
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index c3ca057..0bb659d 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -16,16 +16,15 @@
 
 package com.android.widget;
 
-import android.annotation.NonNull;
 import android.content.Context;
-import android.content.res.Resources;
 import android.media.AudioAttributes;
 import android.media.AudioFocusRequest;
 import android.media.AudioManager;
 import android.media.DataSourceDesc;
 import android.media.MediaMetadata;
-import android.media.MediaPlayer;
-import android.media.MediaPlayerBase;
+import android.media.MediaPlayer2;
+import android.media.MediaPlayer2.MediaPlayer2EventCallback;
+import android.media.MediaPlayer2Impl;
 import android.media.Cea708CaptionRenderer;
 import android.media.ClosedCaptionRenderer;
 import android.media.MediaItem2;
@@ -45,6 +44,7 @@
 import android.media.update.VideoView2Provider;
 import android.media.update.ViewGroupProvider;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.ResultReceiver;
 import android.support.annotation.Nullable;
@@ -58,15 +58,12 @@
 import android.widget.MediaControlView2;
 import android.widget.VideoView2;
 
-import com.android.media.update.ApiHelper;
-import com.android.media.update.R;
+import com.android.media.RoutePlayer;
+import com.android.support.mediarouter.media.MediaItemStatus;
+import com.android.support.mediarouter.media.MediaControlIntent;
 import com.android.support.mediarouter.media.MediaRouter;
 import com.android.support.mediarouter.media.MediaRouteSelector;
-import com.android.support.mediarouter.media.RemotePlaybackClient;
-import com.android.support.mediarouter.media.MediaItemStatus;
-import com.android.support.mediarouter.media.MediaSessionStatus;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -103,13 +100,11 @@
     private VideoTextureView mTextureView;
     private VideoSurfaceView mSurfaceView;
 
-    private MediaPlayer mMediaPlayer;
+    private MediaPlayer2 mMediaPlayer;
+    private DataSourceDesc mDsd;
     private MediaControlView2 mMediaControlView;
     private MediaSession mMediaSession;
     private MediaController mMediaController;
-    private MediaSession.Callback mRouteSessionCallback = new RouteSessionCallback();
-    private MediaRouter mMediaRouter;
-    private MediaRouteSelector mRouteSelector;
     private Metadata mMetadata;
     private MediaMetadata2 mMediaMetadata;
     private boolean mNeedUpdateMediaType;
@@ -142,9 +137,80 @@
     // TODO: Remove mFallbackSpeed when integration with MediaPlayer2's new setPlaybackParams().
     // Refer: https://docs.google.com/document/d/1nzAfns6i2hJ3RkaUre3QMT6wsDedJ5ONLiA_OOBFFX8/edit
     private float mFallbackSpeed;  // keep the original speed before 'pause' is called.
-
     private long mShowControllerIntervalMs;
 
+    private MediaRouter mMediaRouter;
+    private MediaRouteSelector mRouteSelector;
+    private MediaRouter.RouteInfo mRoute;
+    private RoutePlayer mRoutePlayer;
+
+    private final MediaRouter.Callback mRouterCallback = new MediaRouter.Callback() {
+        @Override
+        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
+            if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
+                // Stop local playback (if necessary)
+                resetPlayer();
+                mRoute = route;
+                mRoutePlayer = new RoutePlayer(mInstance.getContext(), route);
+                mRoutePlayer.setPlayerEventCallback(new RoutePlayer.PlayerEventCallback() {
+                    @Override
+                    public void onPlayerStateChanged(MediaItemStatus itemStatus) {
+                        PlaybackState.Builder psBuilder = new PlaybackState.Builder();
+                        psBuilder.setActions(RoutePlayer.PLAYBACK_ACTIONS);
+                        long position = itemStatus.getContentPosition();
+                        switch (itemStatus.getPlaybackState()) {
+                            case MediaItemStatus.PLAYBACK_STATE_PENDING:
+                                psBuilder.setState(PlaybackState.STATE_NONE, position, 0);
+                                mCurrentState = STATE_IDLE;
+                                break;
+                            case MediaItemStatus.PLAYBACK_STATE_PLAYING:
+                                psBuilder.setState(PlaybackState.STATE_PLAYING, position, 1);
+                                mCurrentState = STATE_PLAYING;
+                                break;
+                            case MediaItemStatus.PLAYBACK_STATE_PAUSED:
+                                psBuilder.setState(PlaybackState.STATE_PAUSED, position, 0);
+                                mCurrentState = STATE_PAUSED;
+                                break;
+                            case MediaItemStatus.PLAYBACK_STATE_BUFFERING:
+                                psBuilder.setState(PlaybackState.STATE_BUFFERING, position, 0);
+                                mCurrentState = STATE_PAUSED;
+                                break;
+                            case MediaItemStatus.PLAYBACK_STATE_FINISHED:
+                                psBuilder.setState(PlaybackState.STATE_STOPPED, position, 0);
+                                mCurrentState = STATE_PLAYBACK_COMPLETED;
+                                break;
+                        }
+
+                        PlaybackState pbState = psBuilder.build();
+                        mMediaSession.setPlaybackState(pbState);
+
+                        MediaMetadata.Builder mmBuilder = new MediaMetadata.Builder();
+                        mmBuilder.putLong(MediaMetadata.METADATA_KEY_DURATION,
+                                itemStatus.getContentDuration());
+                        mMediaSession.setMetadata(mmBuilder.build());
+                    }
+                });
+                // Start remote playback (if necessary)
+                mRoutePlayer.openVideo(mDsd);
+            }
+        }
+
+        @Override
+        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route, int reason) {
+            if (mRoute != null && mRoutePlayer != null) {
+                mRoutePlayer.release();
+                mRoutePlayer = null;
+            }
+            if (mRoute == route) {
+                mRoute = null;
+            }
+            if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
+                // TODO: Resume local playback  (if necessary)
+                openVideo(mDsd);
+            }
+        }
+    };
+
     public VideoView2Impl(VideoView2 instance,
             ViewGroupProvider superProvider, ViewGroupProvider privateProvider) {
         super(instance, superProvider, privateProvider);
@@ -196,7 +262,6 @@
         mSubtitleView.setBackgroundColor(0);
         mInstance.addView(mSubtitleView);
 
-        // TODO: Need a common namespace for attributes those are defined in updatable library.
         boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue(
                 "http://schemas.android.com/apk/res/android",
                 "enableControlView", true);
@@ -219,16 +284,20 @@
             Log.d(TAG, "viewType attribute is textureView.");
             // TODO: implement
         }
+
+        MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
+        builder.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
+        builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO);
+        builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
+        mRouteSelector = builder.build();
     }
 
     @Override
     public void setMediaControlView2_impl(MediaControlView2 mediaControlView, long intervalMs) {
         mMediaControlView = mediaControlView;
         mShowControllerIntervalMs = intervalMs;
-        if (mRouteSelector != null) {
-            ((MediaControlView2Impl) mMediaControlView.getProvider())
-                    .setRouteSelector(mRouteSelector);
-        }
+        // TODO: Call MediaControlView2.setRouteSelector only when cast availalbe.
+        ((MediaControlView2Impl) mMediaControlView.getProvider()).setRouteSelector(mRouteSelector);
 
         if (mInstance.isAttachedToWindow()) {
             attachMediaControlView();
@@ -328,30 +397,6 @@
     }
 
     @Override
-    public void setRouteAttributes_impl(List<String> routeCategories, MediaPlayerBase player) {
-        // TODO: implement this.
-    }
-
-    @Override
-    public void setRouteAttributes_impl(@NonNull List<String> routeCategories,
-            MediaSession.Callback sessionPlayer) {
-        MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
-        for (String category : routeCategories) {
-            builder.addControlCategory(category);
-        }
-        mRouteSelector = builder.build();
-        if (mMediaControlView != null) {
-            ((MediaControlView2Impl) mMediaControlView.getProvider())
-                    .setRouteSelector(mRouteSelector);
-        }
-        mMediaRouter = MediaRouter.getInstance(mInstance.getContext());
-        mRouteSessionCallback = sessionPlayer;
-        if (mMediaSession != null) {
-            mMediaRouter.setMediaSession(mMediaSession);
-        }
-    }
-
-    @Override
     public void setVideoPath_impl(String path) {
         mInstance.setVideoUri(Uri.parse(path));
     }
@@ -363,8 +408,9 @@
 
     @Override
     public void setVideoUri_impl(Uri uri, Map<String, String> headers) {
-        mSeekWhenPrepared = 0;
-        openVideo(uri, headers);
+        DataSourceDesc.Builder builder = new DataSourceDesc.Builder();
+        builder.setDataSource(mInstance.getContext(), uri, headers, null);
+        mInstance.setDataSource(builder.build());
     }
 
     @Override
@@ -374,7 +420,9 @@
 
     @Override
     public void setDataSource_impl(DataSourceDesc dsd) {
-        // TODO: implement this
+        mDsd = dsd;
+        mSeekWhenPrepared = 0;
+        openVideo(dsd);
     }
 
     @Override
@@ -431,10 +479,11 @@
         // Create MediaSession
         mMediaSession = new MediaSession(mInstance.getContext(), "VideoView2MediaSession");
         mMediaSession.setCallback(new MediaSessionCallback());
+        mMediaSession.setActive(true);
         mMediaController = mMediaSession.getController();
-        if (mMediaRouter != null) {
-            mMediaRouter.setMediaSession(mMediaSession);
-        }
+        mMediaRouter = MediaRouter.getInstance(mInstance.getContext());
+        mMediaRouter.setMediaSession(mMediaSession);
+        mMediaRouter.addCallback(mRouteSelector, mRouterCallback);
         attachMediaControlView();
         // TODO: remove this after moving MediaSession creating code inside initializing VideoView2
         if (mCurrentState == STATE_PREPARED) {
@@ -545,21 +594,27 @@
     }
 
     private boolean isInPlaybackState() {
-        return (mMediaPlayer != null
+        return (mMediaPlayer != null || mRoutePlayer != null)
                 && mCurrentState != STATE_ERROR
                 && mCurrentState != STATE_IDLE
-                && mCurrentState != STATE_PREPARING);
+                && mCurrentState != STATE_PREPARING;
     }
 
     private boolean needToStart() {
-        return (mMediaPlayer != null
+        return (mMediaPlayer != null || mRoutePlayer != null)
                 && mCurrentState != STATE_PLAYING
-                && mTargetState == STATE_PLAYING);
+                && mTargetState == STATE_PLAYING;
     }
 
-    // Creates a MediaPlayer instance and prepare playback.
-    private void openVideo(Uri uri, Map<String, String> headers) {
+    // Creates a MediaPlayer2 instance and prepare playback.
+    private void openVideo(DataSourceDesc dsd) {
+        Uri uri = dsd.getUri();
+        Map<String, String> headers = dsd.getUriHeaders();
         resetPlayer();
+        if (isRemotePlayback()) {
+            mRoutePlayer.openVideo(dsd);
+            return;
+        }
         if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
             // TODO this should have a focus listener
             AudioFocusRequest focusRequest;
@@ -570,13 +625,13 @@
         }
 
         try {
-            Log.d(TAG, "openVideo(): creating new MediaPlayer instance.");
-            mMediaPlayer = new MediaPlayer();
+            Log.d(TAG, "openVideo(): creating new MediaPlayer2 instance.");
+            mMediaPlayer = new MediaPlayer2Impl();
             mSurfaceView.setMediaPlayer(mMediaPlayer);
             mTextureView.setMediaPlayer(mMediaPlayer);
             mCurrentView.assignSurfaceToMediaPlayer(mMediaPlayer);
 
-            // TODO: create SubtitleController in MediaPlayer, but we need
+            // TODO: create SubtitleController in MediaPlayer2, but we need
             // a context for the subtitle renderers
             final Context context = mInstance.getContext();
             final SubtitleController controller = new SubtitleController(
@@ -588,23 +643,21 @@
             controller.registerRenderer(new SRTRenderer(context));
             mMediaPlayer.setSubtitleAnchor(
                     controller, (SubtitleController.Anchor) mSubtitleView);
-            // TODO: Remove timed text related code later once relevant Renderer is defined.
-            // This is just for debugging purpose.
-            mMediaPlayer.setOnTimedTextListener(mTimedTextListener);
+            Executor executor = new Executor() {
+                @Override
+                public void execute(Runnable runnable) {
+                    runnable.run();
+                }
+            };
+            mMediaPlayer.setMediaPlayer2EventCallback(executor, mMediaPlayer2Callback);
 
-            mMediaPlayer.setOnPreparedListener(mPreparedListener);
-            mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
-            mMediaPlayer.setOnCompletionListener(mCompletionListener);
-            mMediaPlayer.setOnErrorListener(mErrorListener);
-            mMediaPlayer.setOnInfoListener(mInfoListener);
-            mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
             mCurrentBufferPercentage = 0;
-            mMediaPlayer.setDataSource(mInstance.getContext(), uri, headers);
+            mMediaPlayer.setDataSource(dsd);
             mMediaPlayer.setAudioAttributes(mAudioAttributes);
             // we don't set the target state here either, but preserve the
             // target state that was there before.
             mCurrentState = STATE_PREPARING;
-            mMediaPlayer.prepareAsync();
+            mMediaPlayer.prepare();
 
             // Save file name as title since the file may not have a title Metadata.
             mTitle = uri.getPath();
@@ -617,24 +670,12 @@
                 Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState
                         + ", mTargetState=" + mTargetState);
             }
-            /*
-            for (Pair<InputStream, MediaFormat> pending: mPendingSubtitleTracks) {
-                try {
-                    mMediaPlayer.addSubtitleSource(pending.first, pending.second);
-                } catch (IllegalStateException e) {
-                    mInfoListener.onInfo(
-                            mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
-                }
-            }
-            */
-        } catch (IOException | IllegalArgumentException ex) {
+        } catch (IllegalArgumentException ex) {
             Log.w(TAG, "Unable to open content: " + uri, ex);
             mCurrentState = STATE_ERROR;
             mTargetState = STATE_ERROR;
-            mErrorListener.onError(mMediaPlayer,
-                    MediaPlayer.MEDIA_ERROR_UNKNOWN, MediaPlayer.MEDIA_ERROR_IO);
-        } finally {
-            //mPendingSubtitleTracks.clear();
+            mMediaPlayer2Callback.onError(mMediaPlayer, dsd,
+                    MediaPlayer2.MEDIA_ERROR_UNKNOWN, MediaPlayer2.MEDIA_ERROR_IO);
         }
     }
 
@@ -643,9 +684,18 @@
      */
     private void resetPlayer() {
         if (mMediaPlayer != null) {
-            mMediaPlayer.reset();
-            mMediaPlayer.release();
+            final MediaPlayer2 player = mMediaPlayer;
+            new AsyncTask<MediaPlayer2, Void, Void>() {
+                @Override
+                protected Void doInBackground(MediaPlayer2... players) {
+                    // TODO: Fix NPE while MediaPlayer2.close()
+                    //players[0].close();
+                    return null;
+                }
+            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, player);
             mMediaPlayer = null;
+            mTextureView.setMediaPlayer(null);
+            mSurfaceView.setMediaPlayer(null);
             //mPendingSubtitleTracks.clear();
             mCurrentState = STATE_IDLE;
             mTargetState = STATE_IDLE;
@@ -660,8 +710,8 @@
     private void updatePlaybackState() {
         if (mStateBuilder == null) {
             // Get the capabilities of the player for this stream
-            mMetadata = mMediaPlayer.getMetadata(MediaPlayer.METADATA_ALL,
-                    MediaPlayer.BYPASS_METADATA_FILTER);
+            mMetadata = mMediaPlayer.getMetadata(MediaPlayer2.METADATA_ALL,
+                    MediaPlayer2.BYPASS_METADATA_FILTER);
 
             // Add Play action as default
             long playbackActions = PlaybackState.ACTION_PLAY;
@@ -701,6 +751,8 @@
         if (mCurrentState != STATE_ERROR
             && mCurrentState != STATE_IDLE
             && mCurrentState != STATE_PREPARING) {
+            // TODO: this should be replaced with MediaPlayer2.getBufferedPosition() once it is
+            // implemented.
             mStateBuilder.setBufferedPosition(
                     (long) (mCurrentBufferPercentage / 100.0) * mMediaPlayer.getDuration());
         }
@@ -792,8 +844,8 @@
             return false;
         }
         PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo();
-        return (playbackInfo != null)
-                && (playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE);
+        return playbackInfo != null
+                && playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
     }
 
     private void selectOrDeselectSubtitle(boolean select) {
@@ -817,18 +869,18 @@
     }
 
     private void extractTracks() {
-        MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
+        List<MediaPlayer2.TrackInfo> trackInfos = mMediaPlayer.getTrackInfo();
         mVideoTrackIndices = new ArrayList<>();
         mAudioTrackIndices = new ArrayList<>();
         mSubtitleTrackIndices = new ArrayList<>();
-        for (int i = 0; i < trackInfos.length; ++i) {
-            int trackType = trackInfos[i].getTrackType();
-            if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
+        for (int i = 0; i < trackInfos.size(); ++i) {
+            int trackType = trackInfos.get(i).getTrackType();
+            if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
                 mVideoTrackIndices.add(i);
-            } else if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
+            } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
                 mAudioTrackIndices.add(i);
-            } else if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
-                    || trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
+            } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
+                    || trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
                   mSubtitleTrackIndices.add(i);
             }
         }
@@ -842,127 +894,50 @@
         mMediaSession.sendSessionEvent(MediaControlView2Impl.EVENT_UPDATE_TRACK_STATUS, data);
     }
 
-    MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
-            new MediaPlayer.OnVideoSizeChangedListener() {
-                public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
+    MediaPlayer2EventCallback mMediaPlayer2Callback =
+            new MediaPlayer2EventCallback() {
+                @Override
+                public void onVideoSizeChanged(
+                        MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) {
                     if (DEBUG) {
-                        Log.d(TAG, "OnVideoSizeChanged(): size: " + width + "/" + height);
+                        Log.d(TAG, "onVideoSizeChanged(): size: " + width + "/" + height);
                     }
                     mVideoWidth = mp.getVideoWidth();
                     mVideoHeight = mp.getVideoHeight();
                     if (DEBUG) {
-                        Log.d(TAG, "OnVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/"
+                        Log.d(TAG, "onVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/"
                                 + mVideoHeight);
                     }
-
                     if (mVideoWidth != 0 && mVideoHeight != 0) {
                         mInstance.requestLayout();
                     }
                 }
-            };
 
-    MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
-        public void onPrepared(MediaPlayer mp) {
-            if (DEBUG) {
-                Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
-                        + ", mTargetState=" + mTargetState);
-            }
-            mCurrentState = STATE_PREPARED;
-            // Create and set playback state for MediaControlView2
-            updatePlaybackState();
-
-            // TODO: change this to send TrackInfos to MediaControlView2
-            // TODO: create MediaSession when initializing VideoView2
-            if (mMediaSession != null) {
-                extractTracks();
-            }
-
-            if (mMediaControlView != null) {
-                mMediaControlView.setEnabled(true);
-            }
-            int videoWidth = mp.getVideoWidth();
-            int videoHeight = mp.getVideoHeight();
-
-            // mSeekWhenPrepared may be changed after seekTo() call
-            long seekToPosition = mSeekWhenPrepared;
-            if (seekToPosition != 0) {
-                mMediaController.getTransportControls().seekTo(seekToPosition);
-            }
-
-            if (videoWidth != 0 && videoHeight != 0) {
-                if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) {
-                    if (DEBUG) {
-                        Log.i(TAG, "OnPreparedListener() : ");
-                        Log.i(TAG, " video size: " + videoWidth + "/" + videoHeight);
-                        Log.i(TAG, " measuredSize: " + mInstance.getMeasuredWidth() + "/"
-                                + mInstance.getMeasuredHeight());
-                        Log.i(TAG, " viewSize: " + mInstance.getWidth() + "/"
-                                + mInstance.getHeight());
-                    }
-
-                    mVideoWidth = videoWidth;
-                    mVideoHeight = videoHeight;
-                    mInstance.requestLayout();
+                // TODO: Remove timed text related code later once relevant Renderer is defined.
+                // This is just for debugging purpose.
+                @Override
+                public void onTimedText(
+                        MediaPlayer2 mp, DataSourceDesc dsd, TimedText text) {
+                        Log.d(TAG, "TimedText: " + text.getText());
                 }
 
-                if (needToStart()) {
-                    mMediaController.getTransportControls().play();
-                }
-            } else {
-                // We don't know the video size yet, but should start anyway.
-                // The video size might be reported to us later.
-                if (needToStart()) {
-                    mMediaController.getTransportControls().play();
-                }
-            }
-
-            // Get and set duration and title values as MediaMetadata for MediaControlView2
-            MediaMetadata.Builder builder = new MediaMetadata.Builder();
-            if (mMetadata != null && mMetadata.has(Metadata.TITLE)) {
-                mTitle = mMetadata.getString(Metadata.TITLE);
-            }
-            builder.putString(MediaMetadata.METADATA_KEY_TITLE, mTitle);
-            builder.putLong(MediaMetadata.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
-
-            if (mMediaSession != null) {
-                mMediaSession.setMetadata(builder.build());
-
-                // TODO: merge this code with the above code when integrating with MediaSession2.
-                if (mNeedUpdateMediaType) {
-                    mMediaSession.sendSessionEvent(
-                            MediaControlView2Impl.EVENT_UPDATE_MEDIA_TYPE_STATUS, mMediaTypeData);
-                    mNeedUpdateMediaType = false;
-                }
-            }
-        }
-    };
-
-    private MediaPlayer.OnCompletionListener mCompletionListener =
-            new MediaPlayer.OnCompletionListener() {
-                public void onCompletion(MediaPlayer mp) {
-                    mCurrentState = STATE_PLAYBACK_COMPLETED;
-                    mTargetState = STATE_PLAYBACK_COMPLETED;
-                    updatePlaybackState();
-
-                    if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
-                        mAudioManager.abandonAudioFocus(null);
-                    }
-                }
-            };
-
-    private MediaPlayer.OnInfoListener mInfoListener =
-            new MediaPlayer.OnInfoListener() {
-                public boolean onInfo(MediaPlayer mp, int what, int extra) {
-                    if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
+                @Override
+                public void onInfo(
+                        MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
+                    if (what == MediaPlayer2.MEDIA_INFO_METADATA_UPDATE) {
                         extractTracks();
+                    } else if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
+                        this.onPrepared(mp, dsd);
+                    } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
+                        this.onCompletion(mp, dsd);
+                    } else if (what == MediaPlayer2.MEDIA_INFO_BUFFERING_UPDATE) {
+                        this.onBufferingUpdate(mp, dsd, extra);
                     }
-                    return true;
                 }
-            };
 
-    private MediaPlayer.OnErrorListener mErrorListener =
-            new MediaPlayer.OnErrorListener() {
-                public boolean onError(MediaPlayer mp, int frameworkErr, int implErr) {
+                @Override
+                public void onError(
+                        MediaPlayer2 mp, DataSourceDesc dsd, int frameworkErr, int implErr) {
                     if (DEBUG) {
                         Log.d(TAG, "Error: " + frameworkErr + "," + implErr);
                     }
@@ -973,32 +948,103 @@
                     if (mMediaControlView != null) {
                         mMediaControlView.setVisibility(View.GONE);
                     }
-                    return true;
                 }
-            };
 
-    private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =
-            new MediaPlayer.OnBufferingUpdateListener() {
-                public void onBufferingUpdate(MediaPlayer mp, int percent) {
+                private void onPrepared(MediaPlayer2 mp, DataSourceDesc dsd) {
+                    if (DEBUG) {
+                        Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
+                                + ", mTargetState=" + mTargetState);
+                    }
+                    mCurrentState = STATE_PREPARED;
+                    // Create and set playback state for MediaControlView2
+                    updatePlaybackState();
+
+                    // TODO: change this to send TrackInfos to MediaControlView2
+                    // TODO: create MediaSession when initializing VideoView2
+                    if (mMediaSession != null) {
+                        extractTracks();
+                    }
+
+                    if (mMediaControlView != null) {
+                        mMediaControlView.setEnabled(true);
+                    }
+                    int videoWidth = mp.getVideoWidth();
+                    int videoHeight = mp.getVideoHeight();
+
+                    // mSeekWhenPrepared may be changed after seekTo() call
+                    long seekToPosition = mSeekWhenPrepared;
+                    if (seekToPosition != 0) {
+                        mMediaController.getTransportControls().seekTo(seekToPosition);
+                    }
+
+                    if (videoWidth != 0 && videoHeight != 0) {
+                        if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) {
+                            if (DEBUG) {
+                                Log.i(TAG, "OnPreparedListener() : ");
+                                Log.i(TAG, " video size: " + videoWidth + "/" + videoHeight);
+                                Log.i(TAG, " measuredSize: " + mInstance.getMeasuredWidth() + "/"
+                                        + mInstance.getMeasuredHeight());
+                                Log.i(TAG, " viewSize: " + mInstance.getWidth() + "/"
+                                        + mInstance.getHeight());
+                            }
+                            mVideoWidth = videoWidth;
+                            mVideoHeight = videoHeight;
+                            mInstance.requestLayout();
+                        }
+
+                        if (needToStart()) {
+                            mMediaController.getTransportControls().play();
+                        }
+                    } else {
+                        // We don't know the video size yet, but should start anyway.
+                        // The video size might be reported to us later.
+                        if (needToStart()) {
+                            mMediaController.getTransportControls().play();
+                        }
+                    }
+                    // Get and set duration and title values as MediaMetadata for MediaControlView2
+                    MediaMetadata.Builder builder = new MediaMetadata.Builder();
+                    if (mMetadata != null && mMetadata.has(Metadata.TITLE)) {
+                        mTitle = mMetadata.getString(Metadata.TITLE);
+                    }
+                    builder.putString(MediaMetadata.METADATA_KEY_TITLE, mTitle);
+                    builder.putLong(
+                            MediaMetadata.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
+
+                    if (mMediaSession != null) {
+                        mMediaSession.setMetadata(builder.build());
+
+                        // TODO: merge this code with the above code when integrating with
+                        // MediaSession2.
+                        if (mNeedUpdateMediaType) {
+                            mMediaSession.sendSessionEvent(
+                                    MediaControlView2Impl.EVENT_UPDATE_MEDIA_TYPE_STATUS,
+                                    mMediaTypeData);
+                            mNeedUpdateMediaType = false;
+                        }
+                    }
+                }
+
+                private void onCompletion(MediaPlayer2 mp, DataSourceDesc dsd) {
+                    mCurrentState = STATE_PLAYBACK_COMPLETED;
+                    mTargetState = STATE_PLAYBACK_COMPLETED;
+                    updatePlaybackState();
+                    if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) {
+                        mAudioManager.abandonAudioFocus(null);
+                    }
+                }
+
+                private void onBufferingUpdate(MediaPlayer2 mp, DataSourceDesc dsd, int percent) {
                     mCurrentBufferPercentage = percent;
                     updatePlaybackState();
                 }
             };
 
-    // TODO: Remove timed text related code later once relevant Renderer is defined.
-    // This is just for debugging purpose.
-    private MediaPlayer.OnTimedTextListener mTimedTextListener =
-            new MediaPlayer.OnTimedTextListener() {
-                public void onTimedText(MediaPlayer mp, TimedText text) {
-                    Log.d(TAG, "TimedText: " + text.getText());
-                }
-            };
-
     private class MediaSessionCallback extends MediaSession.Callback {
         @Override
         public void onCommand(String command, Bundle args, ResultReceiver receiver) {
             if (isRemotePlayback()) {
-                mRouteSessionCallback.onCommand(command, args, receiver);
+                mRoutePlayer.onCommand(command, args, receiver);
             } else {
                 switch (command) {
                     case MediaControlView2Impl.COMMAND_SHOW_SUBTITLE:
@@ -1028,57 +1074,57 @@
 
         @Override
         public void onPlay() {
-            if (isRemotePlayback()) {
-                mRouteSessionCallback.onPlay();
-            } else {
-                if (isInPlaybackState() && mCurrentView.hasAvailableSurface()) {
+            if (isInPlaybackState() && mCurrentView.hasAvailableSurface()) {
+                if (isRemotePlayback()) {
+                    mRoutePlayer.onPlay();
+                } else {
                     applySpeed();
-                    mMediaPlayer.start();
+                    mMediaPlayer.play();
                     mCurrentState = STATE_PLAYING;
                     updatePlaybackState();
                 }
-                mTargetState = STATE_PLAYING;
-                if (DEBUG) {
-                    Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState
-                            + ", mTargetState=" + mTargetState);
-                }
+                mCurrentState = STATE_PLAYING;
+            }
+            mTargetState = STATE_PLAYING;
+            if (DEBUG) {
+                Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState
+                        + ", mTargetState=" + mTargetState);
             }
             showController();
         }
 
         @Override
         public void onPause() {
-            if (isRemotePlayback()) {
-                mRouteSessionCallback.onPause();
-            } else {
-                if (isInPlaybackState()) {
-                    if (mMediaPlayer.isPlaying()) {
-                        mMediaPlayer.pause();
-                        mCurrentState = STATE_PAUSED;
-                        updatePlaybackState();
-                    }
+            if (isInPlaybackState()) {
+                if (isRemotePlayback()) {
+                    mRoutePlayer.onPause();
+                    mCurrentState = STATE_PAUSED;
+                } else if (mMediaPlayer.isPlaying()) {
+                    mMediaPlayer.pause();
+                    mCurrentState = STATE_PAUSED;
+                    updatePlaybackState();
                 }
-                mTargetState = STATE_PAUSED;
-                if (DEBUG) {
-                    Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState
-                            + ", mTargetState=" + mTargetState);
-                }
+            }
+            mTargetState = STATE_PAUSED;
+            if (DEBUG) {
+                Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState
+                        + ", mTargetState=" + mTargetState);
             }
             showController();
         }
 
         @Override
         public void onSeekTo(long pos) {
-            if (isRemotePlayback()) {
-                mRouteSessionCallback.onSeekTo(pos);
-            } else {
-                if (isInPlaybackState()) {
-                    mMediaPlayer.seekTo(pos, MediaPlayer.SEEK_PREVIOUS_SYNC);
+            if (isInPlaybackState()) {
+                if (isRemotePlayback()) {
+                    mRoutePlayer.onSeekTo(pos);
+                } else {
+                    mMediaPlayer.seekTo(pos, MediaPlayer2.SEEK_PREVIOUS_SYNC);
                     mSeekWhenPrepared = 0;
                     updatePlaybackState();
-                } else {
-                    mSeekWhenPrepared = pos;
                 }
+            } else {
+                mSeekWhenPrepared = pos;
             }
             showController();
         }
@@ -1086,74 +1132,11 @@
         @Override
         public void onStop() {
             if (isRemotePlayback()) {
-                mRouteSessionCallback.onStop();
+                mRoutePlayer.onStop();
             } else {
                 resetPlayer();
             }
             showController();
         }
     }
-
-    private class RouteSessionCallback extends MediaSession.Callback {
-        RemotePlaybackClient mClient;
-
-        RemotePlaybackClient.StatusCallback mStatusCallback =
-                new RemotePlaybackClient.StatusCallback() {
-            @Override
-            public void onItemStatusChanged(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus,
-                    String itemId, MediaItemStatus itemStatus) {
-                // TODO: implement this
-            }
-
-            @Override
-            public void onSessionStatusChanged(Bundle data,
-                    String sessionId, MediaSessionStatus sessionStatus) {
-                // TODO: implement this
-            }
-
-            @Override
-            public void onSessionChanged(String sessionId) {
-                // TODO: implement this
-            }
-        };
-
-        @Override
-        public void onCommand(String command, Bundle args, ResultReceiver receiver) {
-            ensureClient();
-            // TODO: implement this
-        }
-
-        @Override
-        public void onPlay() {
-            ensureClient();
-            // TODO: implement this
-        }
-
-        @Override
-        public void onPause() {
-            ensureClient();
-            // TODO: implement this
-        }
-
-        @Override
-        public void onSeekTo(long pos) {
-            ensureClient();
-            // TODO: implement this
-        }
-
-        @Override
-        public void onStop() {
-            ensureClient();
-            // TODO: implement this
-        }
-
-        private void ensureClient() {
-            if (mClient == null) {
-                mClient = new RemotePlaybackClient(
-                        mInstance.getContext(), mMediaRouter.getSelectedRoute());
-                mClient.setStatusCallback(mStatusCallback);
-            }
-        }
-    }
 }
diff --git a/packages/MediaComponents/src/com/android/widget/VideoViewInterface.java b/packages/MediaComponents/src/com/android/widget/VideoViewInterface.java
index 2a5eb94..854d47e 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoViewInterface.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoViewInterface.java
@@ -17,31 +17,31 @@
 package com.android.widget;
 
 import android.annotation.NonNull;
-import android.media.MediaPlayer;
+import android.media.MediaPlayer2;
 import android.view.View;
 
 interface VideoViewInterface {
     /**
-     * Assigns the view's surface to the given MediaPlayer instance.
+     * Assigns the view's surface to the given MediaPlayer2 instance.
      *
-     * @param mp MediaPlayer
+     * @param mp MediaPlayer2
      * @return true if the surface is successfully assigned, false if not. It will fail to assign
-     *         if any of MediaPlayer or surface is unavailable.
+     *         if any of MediaPlayer2 or surface is unavailable.
      */
-    boolean assignSurfaceToMediaPlayer(MediaPlayer mp);
+    boolean assignSurfaceToMediaPlayer(MediaPlayer2 mp);
     void setSurfaceListener(SurfaceListener l);
     int getViewType();
-    void setMediaPlayer(MediaPlayer mp);
+    void setMediaPlayer(MediaPlayer2 mp);
 
     /**
-     * Takes over oldView. It means that the MediaPlayer will start rendering on this view.
+     * Takes over oldView. It means that the MediaPlayer2 will start rendering on this view.
      * The visibility of oldView will be set as {@link View.GONE}. If the view doesn't have a
-     * MediaPlayer instance or its surface is not available, the actual execution is deferred until
-     * a MediaPlayer instance is set by {@link #setMediaPlayer} or its surface becomes available.
+     * MediaPlayer2 instance or its surface is not available, the actual execution is deferred until
+     * a MediaPlayer2 instance is set by {@link #setMediaPlayer} or its surface becomes available.
      * {@link SurfaceListener.onSurfaceTakeOverDone} will be called when the actual execution is
      * done.
      *
-     * @param oldView The view that MediaPlayer is currently rendering on.
+     * @param oldView The view that MediaPlayer2 is currently rendering on.
      */
     void takeOver(@NonNull VideoViewInterface oldView);
 
diff --git a/packages/MediaComponents/test/Android.mk b/packages/MediaComponents/test/Android.mk
deleted file mode 100644
index 8703b9f..0000000
--- a/packages/MediaComponents/test/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# TODO(jaewan): Copy this to the CTS as well
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-test \
-    mockito-target-minus-junit4 \
-    compatibility-device-util
-
-LOCAL_PACKAGE_NAME := MediaComponentsTest
-include $(BUILD_PACKAGE)
diff --git a/packages/MediaComponents/test/AndroidManifest.xml b/packages/MediaComponents/test/AndroidManifest.xml
deleted file mode 100644
index 5ebe31a..0000000
--- a/packages/MediaComponents/test/AndroidManifest.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.media.test">
-
-    <application android:label="Media API Test">
-        <uses-library android:name="android.test.runner" />
-
-        <activity android:name="android.media.MockActivity" />
-
-        <!-- Keep the test services synced together with the TestUtils.java -->
-        <service android:name="android.media.MockMediaSessionService2">
-            <intent-filter>
-                <action android:name="android.media.MediaSessionService2" />
-            </intent-filter>
-            <meta-data android:name="android.media.session" android:value="TestSession" />
-        </service>
-        <!-- Keep the test services synced together with the MockMediaLibraryService -->
-        <service android:name="android.media.MockMediaLibraryService2">
-            <intent-filter>
-                <action android:name="android.media.MediaLibraryService2" />
-            </intent-filter>
-            <meta-data android:name="android.media.session" android:value="TestLibrary" />
-        </service>
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.media.test"
-        android:label="Media API test" />
-
-</manifest>
diff --git a/packages/MediaComponents/test/src/android/media/MediaBrowser2Test.java b/packages/MediaComponents/test/src/android/media/MediaBrowser2Test.java
deleted file mode 100644
index e58bd02..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaBrowser2Test.java
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.fail;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.media.MediaBrowser2.BrowserCallback;
-import android.media.MediaLibraryService2.MediaLibrarySession;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.TestServiceRegistry.SessionCallbackProxy;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.os.Process;
-import android.support.annotation.CallSuper;
-import android.support.annotation.NonNull;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests {@link MediaBrowser2}.
- * <p>
- * This test inherits {@link MediaController2Test} to ensure that inherited APIs from
- * {@link MediaController2} works cleanly.
- */
-// TODO(jaewan): Implement host-side test so browser and service can run in different processes.
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaBrowser2Test extends MediaController2Test {
-    private static final String TAG = "MediaBrowser2Test";
-
-    @Override
-    TestControllerInterface onCreateController(@NonNull SessionToken2 token,
-            @Nullable TestControllerCallbackInterface callback) {
-        if (callback == null) {
-            callback = new TestBrowserCallbackInterface() {};
-        }
-        return new TestMediaBrowser(mContext, token, new TestBrowserCallback(callback));
-    }
-
-    interface TestBrowserCallbackInterface extends TestControllerCallbackInterface {
-        // Browser specific callbacks
-        default void onGetLibraryRootDone(Bundle rootHints, String rootMediaId, Bundle rootExtra) {}
-        default void onGetItemDone(String mediaId, MediaItem2 result) {}
-        default void onChildrenChanged(String parentId, int itemCount, Bundle extras) {}
-        default void onGetChildrenDone(String parentId, int page, int pageSize,
-                List<MediaItem2> result, Bundle extras) {}
-        default void onSearchResultChanged(String query, int itemCount, Bundle extras) {}
-        default void onGetSearchResultDone(String query, int page, int pageSize,
-                List<MediaItem2> result, Bundle extras) {}
-    }
-
-    @Test
-    public void testGetLibraryRoot() throws InterruptedException {
-        final Bundle param = new Bundle();
-        param.putString(TAG, TAG);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetLibraryRootDone(Bundle rootHints, String rootMediaId,
-                    Bundle rootExtra) {
-                assertTrue(TestUtils.equals(param, rootHints));
-                assertEquals(MockMediaLibraryService2.ROOT_ID, rootMediaId);
-                assertTrue(TestUtils.equals(MockMediaLibraryService2.EXTRAS, rootExtra));
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser =
-                (MediaBrowser2) createController(token,true, callback);
-        browser.getLibraryRoot(param);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetItem() throws InterruptedException {
-        final String mediaId = MockMediaLibraryService2.MEDIA_ID_GET_ITEM;
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetItemDone(String mediaIdOut, MediaItem2 result) {
-                assertEquals(mediaId, mediaIdOut);
-                assertNotNull(result);
-                assertEquals(mediaId, result.getMediaId());
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getItem(mediaId);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetItemNullResult() throws InterruptedException {
-        final String mediaId = "random_media_id";
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetItemDone(String mediaIdOut, MediaItem2 result) {
-                assertEquals(mediaId, mediaIdOut);
-                assertNull(result);
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getItem(mediaId);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetChildren() throws InterruptedException {
-        final String parentId = MockMediaLibraryService2.PARENT_ID;
-        final int page = 4;
-        final int pageSize = 10;
-        final Bundle extras = new Bundle();
-        extras.putString(TAG, TAG);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetChildrenDone(String parentIdOut, int pageOut, int pageSizeOut,
-                    List<MediaItem2> result, Bundle extrasOut) {
-                assertEquals(parentId, parentIdOut);
-                assertEquals(page, pageOut);
-                assertEquals(pageSize, pageSizeOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertNotNull(result);
-
-                int fromIndex = (page - 1) * pageSize;
-                int toIndex = Math.min(page * pageSize, MockMediaLibraryService2.CHILDREN_COUNT);
-
-                // Compare the given results with originals.
-                for (int originalIndex = fromIndex; originalIndex < toIndex; originalIndex++) {
-                    int relativeIndex = originalIndex - fromIndex;
-                    assertEquals(
-                            MockMediaLibraryService2.GET_CHILDREN_RESULT.get(originalIndex)
-                                    .getMediaId(),
-                            result.get(relativeIndex).getMediaId());
-                }
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getChildren(parentId, page, pageSize, extras);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetChildrenEmptyResult() throws InterruptedException {
-        final String parentId = MockMediaLibraryService2.PARENT_ID_NO_CHILDREN;
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetChildrenDone(String parentIdOut, int pageOut, int pageSizeOut,
-                    List<MediaItem2> result, Bundle extrasOut) {
-                assertNotNull(result);
-                assertEquals(0, result.size());
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getChildren(parentId, 1, 1, null);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testGetChildrenNullResult() throws InterruptedException {
-        final String parentId = MockMediaLibraryService2.PARENT_ID_ERROR;
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onGetChildrenDone(String parentIdOut, int pageOut, int pageSizeOut,
-                    List<MediaItem2> result, Bundle extrasOut) {
-                assertNull(result);
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.getChildren(parentId, 1, 1, null);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Ignore
-    @Test
-    public void testSearch() throws InterruptedException {
-        final String query = MockMediaLibraryService2.SEARCH_QUERY;
-        final int page = 4;
-        final int pageSize = 10;
-        final Bundle extras = new Bundle();
-        extras.putString(TAG, TAG);
-
-        final CountDownLatch latchForSearch = new CountDownLatch(1);
-        final CountDownLatch latchForGetSearchResult = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onSearchResultChanged(String queryOut, int itemCount, Bundle extrasOut) {
-                assertEquals(query, queryOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertEquals(MockMediaLibraryService2.SEARCH_RESULT_COUNT, itemCount);
-                latchForSearch.countDown();
-            }
-
-            @Override
-            public void onGetSearchResultDone(String queryOut, int pageOut, int pageSizeOut,
-                    List<MediaItem2> result, Bundle extrasOut) {
-                assertEquals(query, queryOut);
-                assertEquals(page, pageOut);
-                assertEquals(pageSize, pageSizeOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertNotNull(result);
-
-                int fromIndex = (page - 1) * pageSize;
-                int toIndex = Math.min(
-                        page * pageSize, MockMediaLibraryService2.SEARCH_RESULT_COUNT);
-
-                // Compare the given results with originals.
-                for (int originalIndex = fromIndex; originalIndex < toIndex; originalIndex++) {
-                    int relativeIndex = originalIndex - fromIndex;
-                    assertEquals(
-                            MockMediaLibraryService2.SEARCH_RESULT.get(originalIndex).getMediaId(),
-                            result.get(relativeIndex).getMediaId());
-                }
-                latchForGetSearchResult.countDown();
-            }
-        };
-
-        // Request the search.
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.search(query, extras);
-        assertTrue(latchForSearch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-
-        // Get the search result.
-        browser.getSearchResult(query, page, pageSize, extras);
-        assertTrue(latchForGetSearchResult.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testSearchTakesTime() throws InterruptedException {
-        final String query = MockMediaLibraryService2.SEARCH_QUERY_TAKES_TIME;
-        final Bundle extras = new Bundle();
-        extras.putString(TAG, TAG);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onSearchResultChanged(String queryOut, int itemCount, Bundle extrasOut) {
-                assertEquals(query, queryOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertEquals(MockMediaLibraryService2.SEARCH_RESULT_COUNT, itemCount);
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.search(query, extras);
-        assertTrue(latch.await(
-                MockMediaLibraryService2.SEARCH_TIME_IN_MS + WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testSearchEmptyResult() throws InterruptedException {
-        final String query = MockMediaLibraryService2.SEARCH_QUERY_EMPTY_RESULT;
-        final Bundle extras = new Bundle();
-        extras.putString(TAG, TAG);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestBrowserCallbackInterface() {
-            @Override
-            public void onSearchResultChanged(String queryOut, int itemCount, Bundle extrasOut) {
-                assertEquals(query, queryOut);
-                assertTrue(TestUtils.equals(extras, extrasOut));
-                assertEquals(0, itemCount);
-                latch.countDown();
-            }
-        };
-
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token, true, callback);
-        browser.search(query, extras);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testSubscribe() throws InterruptedException {
-        final String testParentId = "testSubscribeId";
-        final Bundle testExtras = new Bundle();
-        testExtras.putString(testParentId, testParentId);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallbackProxy callbackProxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public void onSubscribe(@NonNull MediaLibrarySession session,
-                    @NonNull ControllerInfo info, @NonNull String parentId,
-                    @Nullable Bundle extras) {
-                if (Process.myUid() == info.getUid()) {
-                    assertEquals(testParentId, parentId);
-                    assertTrue(TestUtils.equals(testExtras, extras));
-                    latch.countDown();
-                }
-            }
-        };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(callbackProxy);
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token);
-        browser.subscribe(testParentId, testExtras);
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Ignore
-    @Test
-    public void testUnsubscribe() throws InterruptedException {
-        final String testParentId = "testUnsubscribeId";
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallbackProxy callbackProxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public void onUnsubscribe(@NonNull MediaLibrarySession session,
-                    @NonNull ControllerInfo info, @NonNull String parentId) {
-                if (Process.myUid() == info.getUid()) {
-                    assertEquals(testParentId, parentId);
-                    latch.countDown();
-                }
-            }
-        };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(callbackProxy);
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        MediaBrowser2 browser = (MediaBrowser2) createController(token);
-        browser.unsubscribe(testParentId);
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testBrowserCallback_notifyChildrenChanged() throws InterruptedException {
-        // TODO(jaewan): Add test for the notifyChildrenChanged itself.
-        final String testParentId1 = "testBrowserCallback_notifyChildrenChanged_unexpectedParent";
-        final String testParentId2 = "testBrowserCallback_notifyChildrenChanged";
-        final int testChildrenCount = 101;
-        final Bundle testExtras = new Bundle();
-        testExtras.putString(testParentId1, testParentId1);
-
-        final CountDownLatch latch = new CountDownLatch(3);
-        final SessionCallbackProxy sessionCallbackProxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public CommandGroup onConnect(@NonNull MediaSession2 session,
-                    @NonNull ControllerInfo controller) {
-                if (Process.myUid() == controller.getUid()) {
-                    assertTrue(session instanceof MediaLibrarySession);
-                    if (mSession != null) {
-                        mSession.close();
-                    }
-                    mSession = session;
-                    // Shouldn't trigger onChildrenChanged() for the browser, because it hasn't
-                    // subscribed.
-                    ((MediaLibrarySession) session).notifyChildrenChanged(
-                            testParentId1, testChildrenCount, null);
-                    ((MediaLibrarySession) session).notifyChildrenChanged(
-                            controller, testParentId1, testChildrenCount, null);
-                }
-                return super.onConnect(session, controller);
-            }
-
-            @Override
-            public void onSubscribe(@NonNull MediaLibrarySession session,
-                    @NonNull ControllerInfo info, @NonNull String parentId,
-                    @Nullable Bundle extras) {
-                if (Process.myUid() == info.getUid()) {
-                    session.notifyChildrenChanged(testParentId2, testChildrenCount, null);
-                    session.notifyChildrenChanged(info, testParentId2, testChildrenCount,
-                            testExtras);
-                }
-            }
-        };
-        final TestBrowserCallbackInterface controllerCallbackProxy =
-                new TestBrowserCallbackInterface() {
-                    @Override
-                    public void onChildrenChanged(String parentId, int itemCount, Bundle extras) {
-                        switch ((int) latch.getCount()) {
-                            case 3:
-                                assertEquals(testParentId2, parentId);
-                                assertEquals(testChildrenCount, itemCount);
-                                assertNull(extras);
-                                latch.countDown();
-                                break;
-                            case 2:
-                                assertEquals(testParentId2, parentId);
-                                assertEquals(testChildrenCount, itemCount);
-                                assertTrue(TestUtils.equals(testExtras, extras));
-                                latch.countDown();
-                                break;
-                            default:
-                                // Unexpected call.
-                                fail();
-                        }
-                    }
-                };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(sessionCallbackProxy);
-        final SessionToken2 token = MockMediaLibraryService2.getToken(mContext);
-        final MediaBrowser2 browser = (MediaBrowser2) createController(
-                token, true, controllerCallbackProxy);
-        assertTrue(mSession instanceof MediaLibrarySession);
-        browser.subscribe(testParentId2, null);
-        // This ensures that onChildrenChanged() is only called for the expected reasons.
-        assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    public static class TestBrowserCallback extends BrowserCallback
-            implements WaitForConnectionInterface {
-        private final TestControllerCallbackInterface mCallbackProxy;
-        public final CountDownLatch connectLatch = new CountDownLatch(1);
-        public final CountDownLatch disconnectLatch = new CountDownLatch(1);
-
-        TestBrowserCallback(TestControllerCallbackInterface callbackProxy) {
-            if (callbackProxy == null) {
-                throw new IllegalArgumentException("Callback proxy shouldn't be null. Test bug");
-            }
-            mCallbackProxy = callbackProxy;
-        }
-
-        @CallSuper
-        @Override
-        public void onConnected(MediaController2 controller, CommandGroup commands) {
-            connectLatch.countDown();
-        }
-
-        @CallSuper
-        @Override
-        public void onDisconnected(MediaController2 controller) {
-            disconnectLatch.countDown();
-        }
-
-        @Override
-        public void onPlaybackStateChanged(MediaController2 controller, PlaybackState2 state) {
-            mCallbackProxy.onPlaybackStateChanged(state);
-        }
-
-        @Override
-        public void onPlaylistParamsChanged(MediaController2 controller, PlaylistParams params) {
-            mCallbackProxy.onPlaylistParamsChanged(params);
-        }
-
-        @Override
-        public void onPlaybackInfoChanged(MediaController2 controller,
-                MediaController2.PlaybackInfo info) {
-            mCallbackProxy.onPlaybackInfoChanged(info);
-        }
-
-        @Override
-        public void onCustomCommand(MediaController2 controller, Command command, Bundle args,
-                ResultReceiver receiver) {
-            mCallbackProxy.onCustomCommand(command, args, receiver);
-        }
-
-        @Override
-        public void onCustomLayoutChanged(MediaController2 controller, List<CommandButton> layout) {
-            mCallbackProxy.onCustomLayoutChanged(layout);
-        }
-
-        @Override
-        public void onAllowedCommandsChanged(MediaController2 controller, CommandGroup commands) {
-            mCallbackProxy.onAllowedCommandsChanged(commands);
-        }
-
-        @Override
-        public void onGetLibraryRootDone(MediaBrowser2 browser, Bundle rootHints,
-                String rootMediaId, Bundle rootExtra) {
-            super.onGetLibraryRootDone(browser, rootHints, rootMediaId, rootExtra);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onGetLibraryRootDone(rootHints, rootMediaId, rootExtra);
-            }
-        }
-
-        @Override
-        public void onGetItemDone(MediaBrowser2 browser, String mediaId, MediaItem2 result) {
-            super.onGetItemDone(browser, mediaId, result);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy).onGetItemDone(mediaId, result);
-            }
-        }
-
-        @Override
-        public void onGetChildrenDone(MediaBrowser2 browser, String parentId, int page,
-                int pageSize, List<MediaItem2> result, Bundle extras) {
-            super.onGetChildrenDone(browser, parentId, page, pageSize, result, extras);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onGetChildrenDone(parentId, page, pageSize, result, extras);
-            }
-        }
-
-        @Override
-        public void onSearchResultChanged(MediaBrowser2 browser, String query, int itemCount,
-                Bundle extras) {
-            super.onSearchResultChanged(browser, query, itemCount, extras);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onSearchResultChanged(query, itemCount, extras);
-            }
-        }
-
-        @Override
-        public void onGetSearchResultDone(MediaBrowser2 browser, String query, int page,
-                int pageSize, List<MediaItem2> result, Bundle extras) {
-            super.onGetSearchResultDone(browser, query, page, pageSize, result, extras);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onGetSearchResultDone(query, page, pageSize, result, extras);
-            }
-        }
-
-        @Override
-        public void onChildrenChanged(MediaBrowser2 browser, String parentId, int itemCount,
-                Bundle extras) {
-            super.onChildrenChanged(browser, parentId, itemCount, extras);
-            if (mCallbackProxy instanceof TestBrowserCallbackInterface) {
-                ((TestBrowserCallbackInterface) mCallbackProxy)
-                        .onChildrenChanged(parentId, itemCount, extras);
-            }
-        }
-
-        @Override
-        public void waitForConnect(boolean expect) throws InterruptedException {
-            if (expect) {
-                assertTrue(connectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            } else {
-                assertFalse(connectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-
-        @Override
-        public void waitForDisconnect(boolean expect) throws InterruptedException {
-            if (expect) {
-                assertTrue(disconnectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            } else {
-                assertFalse(disconnectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-    }
-
-    public class TestMediaBrowser extends MediaBrowser2 implements TestControllerInterface {
-        private final BrowserCallback mCallback;
-
-        public TestMediaBrowser(@NonNull Context context, @NonNull SessionToken2 token,
-                @NonNull ControllerCallback callback) {
-            super(context, token, sHandlerExecutor, (BrowserCallback) callback);
-            mCallback = (BrowserCallback) callback;
-        }
-
-        @Override
-        public BrowserCallback getCallback() {
-            return mCallback;
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaController2Test.java b/packages/MediaComponents/test/src/android/media/MediaController2Test.java
deleted file mode 100644
index bd5f031..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaController2Test.java
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.MediaSession2.SessionCallback;
-import android.media.TestServiceRegistry.SessionCallbackProxy;
-import android.media.TestUtils.SyncHandler;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Process;
-import android.os.ResultReceiver;
-import android.support.annotation.NonNull;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static android.media.TestUtils.ensurePlaylistParamsModeEquals;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests {@link MediaController2}.
- */
-// TODO(jaewan): Implement host-side test so controller and session can run in different processes.
-// TODO(jaewan): Fix flaky failure -- see MediaController2Impl.getController()
-// TODO(jaeawn): Revisit create/close session in the sHandler. It's no longer necessary.
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-@FlakyTest
-public class MediaController2Test extends MediaSession2TestBase {
-    private static final String TAG = "MediaController2Test";
-
-    PendingIntent mIntent;
-    MediaSession2 mSession;
-    MediaController2 mController;
-    MockPlayer mPlayer;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        final Intent sessionActivity = new Intent(mContext, MockActivity.class);
-        // Create this test specific MediaSession2 to use our own Handler.
-        mIntent = PendingIntent.getActivity(mContext, 0, sessionActivity, 0);
-
-        mPlayer = new MockPlayer(1);
-        mSession = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {})
-                .setSessionActivity(mIntent)
-                .setId(TAG).build();
-        mController = createController(mSession.getToken());
-        TestServiceRegistry.getInstance().setHandler(sHandler);
-    }
-
-    @After
-    @Override
-    public void cleanUp() throws Exception {
-        super.cleanUp();
-        if (mSession != null) {
-            mSession.close();
-        }
-        TestServiceRegistry.getInstance().cleanUp();
-    }
-
-    @Test
-    public void testPlay() throws InterruptedException {
-        mController.play();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mPlayCalled);
-    }
-
-    @Test
-    public void testPause() throws InterruptedException {
-        mController.pause();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mPauseCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testSkipToPreviousItem() throws InterruptedException {
-        mController.skipToPreviousItem();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mSkipToPreviousCalled);
-    }
-
-    @Test
-    public void testSkipToNextItem() throws InterruptedException {
-        mController.skipToNextItem();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mSkipToNextCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testStop() throws InterruptedException {
-        mController.stop();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mStopCalled);
-    }
-
-    @Test
-    public void testPrepare() throws InterruptedException {
-        mController.prepare();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mPrepareCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testFastForward() throws InterruptedException {
-        mController.fastForward();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mFastForwardCalled);
-    }
-
-    @Ignore
-    @Test
-    public void testRewind() throws InterruptedException {
-        mController.rewind();
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mRewindCalled);
-    }
-
-    @Test
-    public void testSeekTo() throws InterruptedException {
-        final long seekPosition = 12125L;
-        mController.seekTo(seekPosition);
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mSeekToCalled);
-        assertEquals(seekPosition, mPlayer.mSeekPosition);
-    }
-
-    // TODO(jaewan): Re-enable this test
-    /*
-    @Test
-    public void testSetCurrentPlaylistItem() throws InterruptedException {
-        final
-        final int itemIndex = 9;
-        mController.skipToPlaylistItem(itemIndex);
-        try {
-            assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e) {
-            fail(e.getMessage());
-        }
-        assertTrue(mPlayer.mSetCurrentPlaylistCalled);
-        assertEquals(itemIndex, mPlayer.mCurrentItem);
-    }
-    */
-
-    @Test
-    public void testGetSessionActivity() throws InterruptedException {
-        PendingIntent sessionActivity = mController.getSessionActivity();
-        assertEquals(mContext.getPackageName(), sessionActivity.getCreatorPackage());
-        assertEquals(Process.myUid(), sessionActivity.getCreatorUid());
-    }
-
-    @Ignore
-    @Test
-    public void testGetSetPlaylistParams() throws Exception {
-        final PlaylistParams params = new PlaylistParams(mContext,
-                PlaylistParams.REPEAT_MODE_ALL,
-                PlaylistParams.SHUFFLE_MODE_ALL,
-                null /* PlaylistMetadata */);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaylistParamsChanged(PlaylistParams givenParams) {
-                ensurePlaylistParamsModeEquals(params, givenParams);
-                latch.countDown();
-            }
-        };
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        controller.setPlaylistParams(params);
-
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        ensurePlaylistParamsModeEquals(params, mSession.getPlaylistParams());
-        ensurePlaylistParamsModeEquals(params, controller.getPlaylistParams());
-    }
-
-    @Test
-    public void testSetVolumeTo() throws Exception {
-        final int maxVolume = 100;
-        final int currentVolume = 23;
-        final int volumeControlType = VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-        TestVolumeProvider volumeProvider =
-                new TestVolumeProvider(mContext, volumeControlType, maxVolume, currentVolume);
-
-        mSession.updatePlayer(new MockPlayer(0), null, volumeProvider);
-        final MediaController2 controller = createController(mSession.getToken(), true, null);
-
-        final int targetVolume = 50;
-        controller.setVolumeTo(targetVolume, 0 /* flags */);
-        assertTrue(volumeProvider.mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertTrue(volumeProvider.mSetVolumeToCalled);
-        assertEquals(targetVolume, volumeProvider.mVolume);
-    }
-
-    @Test
-    public void testAdjustVolume() throws Exception {
-        final int maxVolume = 100;
-        final int currentVolume = 23;
-        final int volumeControlType = VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-        TestVolumeProvider volumeProvider =
-                new TestVolumeProvider(mContext, volumeControlType, maxVolume, currentVolume);
-
-        mSession.updatePlayer(new MockPlayer(0), null, volumeProvider);
-        final MediaController2 controller = createController(mSession.getToken(), true, null);
-
-        final int direction = AudioManager.ADJUST_RAISE;
-        controller.adjustVolume(direction, 0 /* flags */);
-        assertTrue(volumeProvider.mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertTrue(volumeProvider.mAdjustVolumeCalled);
-        assertEquals(direction, volumeProvider.mDirection);
-    }
-
-    @Test
-    public void testGetPackageName() {
-        assertEquals(mContext.getPackageName(), mController.getSessionToken().getPackageName());
-    }
-
-    // This also tests getPlaybackState().
-    @Ignore
-    @Test
-    public void testControllerCallback_onPlaybackStateChanged() throws InterruptedException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaybackStateChanged(PlaybackState2 state) {
-                // Called only once when the player's playback state is changed after this.
-                assertEquals(PlaybackState2.STATE_PAUSED, state.getState());
-                latch.countDown();
-            }
-        };
-        mPlayer.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PLAYING));
-        mController = createController(mSession.getToken(), true, callback);
-        assertEquals(PlaybackState2.STATE_PLAYING, mController.getPlaybackState().getState());
-        mPlayer.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PAUSED));
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertEquals(PlaybackState2.STATE_PAUSED, mController.getPlaybackState().getState());
-    }
-
-    @Test
-    public void testSendCustomCommand() throws InterruptedException {
-        // TODO(jaewan): Need to revisit with the permission.
-        final Command testCommand =
-                new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE);
-        final Bundle testArgs = new Bundle();
-        testArgs.putString("args", "testSendCustomAction");
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onCustomCommand(MediaSession2 session, ControllerInfo controller,
-                    Command customCommand, Bundle args, ResultReceiver cb) {
-                super.onCustomCommand(session, controller, customCommand, args, cb);
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(testCommand, customCommand);
-                assertTrue(TestUtils.equals(testArgs, args));
-                assertNull(cb);
-                latch.countDown();
-            }
-        };
-        mSession.close();
-        mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback).setId(TAG).build();
-        final MediaController2 controller = createController(mSession.getToken());
-        controller.sendCustomCommand(testCommand, testArgs, null);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testControllerCallback_onConnected() throws InterruptedException {
-        // createController() uses controller callback to wait until the controller becomes
-        // available.
-        MediaController2 controller = createController(mSession.getToken());
-        assertNotNull(controller);
-    }
-
-    @Test
-    public void testControllerCallback_sessionRejects() throws InterruptedException {
-        final MediaSession2.SessionCallback sessionCallback = new SessionCallback(mContext) {
-            @Override
-            public MediaSession2.CommandGroup onConnect(MediaSession2 session,
-                    ControllerInfo controller) {
-                return null;
-            }
-        };
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                    .setSessionCallback(sHandlerExecutor, sessionCallback).build();
-        });
-        MediaController2 controller =
-                createController(mSession.getToken(), false, null);
-        assertNotNull(controller);
-        waitForConnect(controller, false);
-        waitForDisconnect(controller, true);
-    }
-
-    @Test
-    public void testControllerCallback_releaseSession() throws InterruptedException {
-        sHandler.postAndSync(() -> {
-            mSession.close();
-        });
-        waitForDisconnect(mController, true);
-    }
-
-    @Test
-    public void testControllerCallback_release() throws InterruptedException {
-        mController.close();
-        waitForDisconnect(mController, true);
-    }
-
-    @Test
-    public void testPlayFromSearch() throws InterruptedException {
-        final String request = "random query";
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPlayFromSearch(MediaSession2 session, ControllerInfo controller,
-                    String query, Bundle extras) {
-                super.onPlayFromSearch(session, controller, query, extras);
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, query);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPlayFromSearch").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.playFromSearch(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testPlayFromUri() throws InterruptedException {
-        final Uri request = Uri.parse("foo://boo");
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPlayFromUri(MediaSession2 session, ControllerInfo controller, Uri uri,
-                    Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, uri);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPlayFromUri").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.playFromUri(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testPlayFromMediaId() throws InterruptedException {
-        final String request = "media_id";
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPlayFromMediaId(MediaSession2 session, ControllerInfo controller,
-                    String mediaId, Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, mediaId);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPlayFromMediaId").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.playFromMediaId(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-
-    @Test
-    public void testPrepareFromSearch() throws InterruptedException {
-        final String request = "random query";
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPrepareFromSearch(MediaSession2 session, ControllerInfo controller,
-                    String query, Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, query);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPrepareFromSearch").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.prepareFromSearch(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testPrepareFromUri() throws InterruptedException {
-        final Uri request = Uri.parse("foo://boo");
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPrepareFromUri(MediaSession2 session, ControllerInfo controller, Uri uri,
-                    Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, uri);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPrepareFromUri").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.prepareFromUri(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testPrepareFromMediaId() throws InterruptedException {
-        final String request = "media_id";
-        final Bundle bundle = new Bundle();
-        bundle.putString("key", "value");
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onPrepareFromMediaId(MediaSession2 session, ControllerInfo controller,
-                    String mediaId, Bundle extras) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(request, mediaId);
-                assertTrue(TestUtils.equals(bundle, extras));
-                latch.countDown();
-            }
-        };
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testPrepareFromMediaId").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.prepareFromMediaId(request, bundle);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testSetRating() throws InterruptedException {
-        final int ratingType = Rating2.RATING_5_STARS;
-        final float ratingValue = 3.5f;
-        final Rating2 rating = Rating2.newStarRating(mContext, ratingType, ratingValue);
-        final String mediaId = "media_id";
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback callback = new SessionCallback(mContext) {
-            @Override
-            public void onSetRating(MediaSession2 session, ControllerInfo controller,
-                    String mediaIdOut, Rating2 ratingOut) {
-                assertEquals(mContext.getPackageName(), controller.getPackageName());
-                assertEquals(mediaId, mediaIdOut);
-                assertEquals(rating, ratingOut);
-                latch.countDown();
-            }
-        };
-
-        try (MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, callback)
-                .setId("testSetRating").build()) {
-            MediaController2 controller = createController(session.getToken());
-            controller.setRating(mediaId, rating);
-            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testIsConnected() throws InterruptedException {
-        assertTrue(mController.isConnected());
-        sHandler.postAndSync(()->{
-            mSession.close();
-        });
-        // postAndSync() to wait until the disconnection is propagated.
-        sHandler.postAndSync(()->{
-            assertFalse(mController.isConnected());
-        });
-    }
-
-    /**
-     * Test potential deadlock for calls between controller and session.
-     */
-    @Test
-    public void testDeadlock() throws InterruptedException {
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mSession = null;
-        });
-
-        // Two more threads are needed not to block test thread nor test wide thread (sHandler).
-        final HandlerThread sessionThread = new HandlerThread("testDeadlock_session");
-        final HandlerThread testThread = new HandlerThread("testDeadlock_test");
-        sessionThread.start();
-        testThread.start();
-        final SyncHandler sessionHandler = new SyncHandler(sessionThread.getLooper());
-        final Handler testHandler = new Handler(testThread.getLooper());
-        final CountDownLatch latch = new CountDownLatch(1);
-        try {
-            final MockPlayer player = new MockPlayer(0);
-            sessionHandler.postAndSync(() -> {
-                mSession = new MediaSession2.Builder(mContext)
-                        .setPlayer(mPlayer)
-                        .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {})
-                        .setId("testDeadlock").build();
-            });
-            final MediaController2 controller = createController(mSession.getToken());
-            testHandler.post(() -> {
-                final PlaybackState2 state = createPlaybackState(PlaybackState2.STATE_ERROR);
-                for (int i = 0; i < 100; i++) {
-                    // triggers call from session to controller.
-                    player.notifyPlaybackState(state);
-                    // triggers call from controller to session.
-                    controller.play();
-
-                    // Repeat above
-                    player.notifyPlaybackState(state);
-                    controller.pause();
-                    player.notifyPlaybackState(state);
-                    controller.stop();
-                    player.notifyPlaybackState(state);
-                    controller.skipToNextItem();
-                    player.notifyPlaybackState(state);
-                    controller.skipToPreviousItem();
-                }
-                // This may hang if deadlock happens.
-                latch.countDown();
-            });
-            assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        } finally {
-            if (mSession != null) {
-                sessionHandler.postAndSync(() -> {
-                    // Clean up here because sessionHandler will be removed afterwards.
-                    mSession.close();
-                    mSession = null;
-                });
-            }
-            if (sessionThread != null) {
-                sessionThread.quitSafely();
-            }
-            if (testThread != null) {
-                testThread.quitSafely();
-            }
-        }
-    }
-
-    @Test
-    public void testGetServiceToken() {
-        SessionToken2 token = TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID);
-        assertNotNull(token);
-        assertEquals(mContext.getPackageName(), token.getPackageName());
-        assertEquals(MockMediaSessionService2.ID, token.getId());
-        assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-    }
-
-    @Test
-    public void testConnectToService_sessionService() throws InterruptedException {
-        testConnectToService(MockMediaSessionService2.ID);
-    }
-
-    @Ignore
-    @Test
-    public void testConnectToService_libraryService() throws InterruptedException {
-        testConnectToService(MockMediaLibraryService2.ID);
-    }
-
-    public void testConnectToService(String id) throws InterruptedException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallbackProxy proxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public CommandGroup onConnect(@NonNull MediaSession2 session,
-                    @NonNull ControllerInfo controller) {
-                if (Process.myUid() == controller.getUid()) {
-                    if (mSession != null) {
-                        mSession.close();
-                    }
-                    mSession = session;
-                    mPlayer = (MockPlayer) session.getPlayer();
-                    assertEquals(mContext.getPackageName(), controller.getPackageName());
-                    assertFalse(controller.isTrusted());
-                    latch.countDown();
-                }
-                return super.onConnect(session, controller);
-            }
-        };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(proxy);
-
-        mController = createController(TestUtils.getServiceToken(mContext, id));
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Test command from controller to session service
-        mController.play();
-        assertTrue(mPlayer.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertTrue(mPlayer.mPlayCalled);
-
-        // Test command from session service to controller
-        // TODO(jaewan): Add equivalent tests again
-        /*
-        final CountDownLatch latch = new CountDownLatch(1);
-        mController.registerPlayerEventCallback((state) -> {
-            assertNotNull(state);
-            assertEquals(PlaybackState.STATE_REWINDING, state.getState());
-            latch.countDown();
-        }, sHandler);
-        mPlayer.notifyPlaybackState(
-                TestUtils.createPlaybackState(PlaybackState.STATE_REWINDING));
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        */
-    }
-
-    @Test
-    public void testControllerAfterSessionIsGone_session() throws InterruptedException {
-        testControllerAfterSessionIsGone(mSession.getToken().getId());
-    }
-
-    // TODO(jaewan): Re-enable this test
-    @Ignore
-    @Test
-    public void testControllerAfterSessionIsGone_sessionService() throws InterruptedException {
-        /*
-        connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID));
-        testControllerAfterSessionIsGone(MockMediaSessionService2.ID);
-        */
-    }
-
-    @Test
-    public void testClose_beforeConnected() throws InterruptedException {
-        MediaController2 controller =
-                createController(mSession.getToken(), false, null);
-        controller.close();
-    }
-
-    @Test
-    public void testClose_twice() throws InterruptedException {
-        mController.close();
-        mController.close();
-    }
-
-    @Test
-    public void testClose_session() throws InterruptedException {
-        final String id = mSession.getToken().getId();
-        mController.close();
-        // close is done immediately for session.
-        testNoInteraction();
-
-        // Test whether the controller is notified about later close of the session or
-        // re-creation.
-        testControllerAfterSessionIsGone(id);
-    }
-
-    @Test
-    public void testClose_sessionService() throws InterruptedException {
-        testCloseFromService(MockMediaSessionService2.ID);
-    }
-
-    @Test
-    public void testClose_libraryService() throws InterruptedException {
-        testCloseFromService(MockMediaLibraryService2.ID);
-    }
-
-    private void testCloseFromService(String id) throws InterruptedException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallbackProxy proxy = new SessionCallbackProxy(mContext) {
-            @Override
-            public void onServiceDestroyed() {
-                latch.countDown();
-            }
-        };
-        TestServiceRegistry.getInstance().setSessionCallbackProxy(proxy);
-        mController = createController(TestUtils.getServiceToken(mContext, id));
-        mController.close();
-        // Wait until close triggers onDestroy() of the session service.
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertNull(TestServiceRegistry.getInstance().getServiceInstance());
-        testNoInteraction();
-
-        // Test whether the controller is notified about later close of the session or
-        // re-creation.
-        testControllerAfterSessionIsGone(id);
-    }
-
-    private void testControllerAfterSessionIsGone(final String id) throws InterruptedException {
-        sHandler.postAndSync(() -> {
-            // TODO(jaewan): Use Session.close later when we add the API.
-            mSession.close();
-        });
-        waitForDisconnect(mController, true);
-        testNoInteraction();
-
-        // Ensure that the controller cannot use newly create session with the same ID.
-        sHandler.postAndSync(() -> {
-            // Recreated session has different session stub, so previously created controller
-            // shouldn't be available.
-            mSession = new MediaSession2.Builder(mContext)
-                    .setPlayer(mPlayer)
-                    .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {})
-                    .setId(id).build();
-        });
-        testNoInteraction();
-    }
-
-    private void testNoInteraction() throws InterruptedException {
-        // TODO: Uncomment
-        /*
-        final CountDownLatch latch = new CountDownLatch(1);
-        final PlayerEventCallback callback = new PlayerEventCallback() {
-            @Override
-            public void onPlaybackStateChanged(PlaybackState2 state) {
-                fail("Controller shouldn't be notified about change in session after the close.");
-                latch.countDown();
-            }
-        };
-        */
-
-        // TODO(jaewan): Add equivalent tests again
-        /*
-        mController.registerPlayerEventCallback(playbackListener, sHandler);
-        mPlayer.notifyPlaybackState(TestUtils.createPlaybackState(PlaybackState.STATE_BUFFERING));
-        assertFalse(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        mController.unregisterPlayerEventCallback(playbackListener);
-        */
-    }
-
-    // TODO(jaewan): Add  test for service connect rejection, when we differentiate session
-    //               active/inactive and connection accept/refuse
-
-    class TestVolumeProvider extends VolumeProvider2 {
-        final CountDownLatch mLatch = new CountDownLatch(1);
-        boolean mSetVolumeToCalled;
-        boolean mAdjustVolumeCalled;
-        int mVolume;
-        int mDirection;
-
-        public TestVolumeProvider(Context context, int controlType, int maxVolume,
-                int currentVolume) {
-            super(context, controlType, maxVolume, currentVolume);
-        }
-
-        @Override
-        public void onSetVolumeTo(int volume) {
-            mSetVolumeToCalled = true;
-            mVolume = volume;
-            mLatch.countDown();
-        }
-
-        @Override
-        public void onAdjustVolume(int direction) {
-            mAdjustVolumeCalled = true;
-            mDirection = direction;
-            mLatch.countDown();
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaMetadata2Test.java b/packages/MediaComponents/test/src/android/media/MediaMetadata2Test.java
deleted file mode 100644
index 06b51bd..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaMetadata2Test.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import android.content.Context;
-import android.media.MediaMetadata2.Builder;
-import android.os.Bundle;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.test.InstrumentationRegistry;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaMetadata2Test {
-    private Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @Test
-    public void testBuilder() {
-        final Bundle extras = new Bundle();
-        extras.putString("MediaMetadata2Test", "testBuilder");
-        final String title = "title";
-        final long discNumber = 10;
-        final Rating2 rating = Rating2.newThumbRating(mContext, true);
-
-        MediaMetadata2.Builder builder = new Builder(mContext);
-        builder.setExtras(extras);
-        builder.putString(MediaMetadata2.METADATA_KEY_DISPLAY_TITLE, title);
-        builder.putLong(MediaMetadata2.METADATA_KEY_DISC_NUMBER, discNumber);
-        builder.putRating(MediaMetadata2.METADATA_KEY_USER_RATING, rating);
-
-        MediaMetadata2 metadata = builder.build();
-        assertTrue(TestUtils.equals(extras, metadata.getExtras()));
-        assertEquals(title, metadata.getString(MediaMetadata2.METADATA_KEY_DISPLAY_TITLE));
-        assertEquals(discNumber, metadata.getLong(MediaMetadata2.METADATA_KEY_DISC_NUMBER));
-        assertEquals(rating, metadata.getRating(MediaMetadata2.METADATA_KEY_USER_RATING));
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSession2Test.java b/packages/MediaComponents/test/src/android/media/MediaSession2Test.java
deleted file mode 100644
index afb191f..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaSession2Test.java
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static android.media.AudioAttributes.CONTENT_TYPE_MUSIC;
-import static android.media.TestUtils.ensurePlaylistParamsModeEquals;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.media.MediaController2.PlaybackInfo;
-import android.media.MediaSession2.Builder;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.MediaSession2.SessionCallback;
-import android.os.Bundle;
-import android.os.Process;
-import android.os.ResultReceiver;
-import android.support.annotation.NonNull;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests {@link MediaSession2}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaSession2Test extends MediaSession2TestBase {
-    private static final String TAG = "MediaSession2Test";
-
-    private MediaSession2 mSession;
-    private MockPlayer mPlayer;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mPlayer = new MockPlayer(0);
-        mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {}).build();
-    }
-
-    @After
-    @Override
-    public void cleanUp() throws Exception {
-        super.cleanUp();
-        mSession.close();
-    }
-
-    @Ignore
-    @Test
-    public void testBuilder() throws Exception {
-        try {
-            MediaSession2.Builder builder = new Builder(mContext);
-            fail("null player shouldn't be allowed");
-        } catch (IllegalArgumentException e) {
-            // expected. pass-through
-        }
-        MediaSession2.Builder builder = new Builder(mContext).setPlayer(mPlayer);
-        try {
-            builder.setId(null);
-            fail("null id shouldn't be allowed");
-        } catch (IllegalArgumentException e) {
-            // expected. pass-through
-        }
-    }
-
-    @Test
-    public void testUpdatePlayer() throws Exception {
-        MockPlayer player = new MockPlayer(0);
-        // Test if setPlayer doesn't crash with various situations.
-        mSession.updatePlayer(mPlayer, null, null);
-        mSession.updatePlayer(player, null, null);
-        mSession.close();
-    }
-
-    @Test
-    public void testSetPlayer_playbackInfo() throws Exception {
-        MockPlayer player = new MockPlayer(0);
-        AudioAttributes attrs = new AudioAttributes.Builder()
-                .setContentType(CONTENT_TYPE_MUSIC)
-                .build();
-        player.setAudioAttributes(attrs);
-
-        final int maxVolume = 100;
-        final int currentVolume = 23;
-        final int volumeControlType = VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-        VolumeProvider2 volumeProvider =
-                new VolumeProvider2(mContext, volumeControlType, maxVolume, currentVolume) { };
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaybackInfoChanged(PlaybackInfo info) {
-                assertEquals(MediaController2.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
-                        info.getPlaybackType());
-                assertEquals(attrs, info.getAudioAttributes());
-                assertEquals(volumeControlType, info.getPlaybackType());
-                assertEquals(maxVolume, info.getMaxVolume());
-                assertEquals(currentVolume, info.getCurrentVolume());
-                latch.countDown();
-            }
-        };
-
-        mSession.updatePlayer(player, null, null);
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        PlaybackInfo info = controller.getPlaybackInfo();
-        assertNotNull(info);
-        assertEquals(PlaybackInfo.PLAYBACK_TYPE_LOCAL, info.getPlaybackType());
-        assertEquals(attrs, info.getAudioAttributes());
-        AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        int localVolumeControlType = manager.isVolumeFixed()
-                ? VolumeProvider2.VOLUME_CONTROL_FIXED : VolumeProvider2.VOLUME_CONTROL_ABSOLUTE;
-        assertEquals(localVolumeControlType, info.getControlType());
-        assertEquals(manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), info.getMaxVolume());
-        assertEquals(manager.getStreamVolume(AudioManager.STREAM_MUSIC), info.getCurrentVolume());
-
-        mSession.updatePlayer(player, null, volumeProvider);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-
-        info = controller.getPlaybackInfo();
-        assertNotNull(info);
-        assertEquals(PlaybackInfo.PLAYBACK_TYPE_REMOTE, info.getPlaybackType());
-        assertEquals(attrs, info.getAudioAttributes());
-        assertEquals(volumeControlType, info.getControlType());
-        assertEquals(maxVolume, info.getMaxVolume());
-        assertEquals(currentVolume, info.getCurrentVolume());
-    }
-
-    @Test
-    public void testPlay() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.play();
-            assertTrue(mPlayer.mPlayCalled);
-        });
-    }
-
-    @Test
-    public void testPause() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.pause();
-            assertTrue(mPlayer.mPauseCalled);
-        });
-    }
-
-    @Ignore
-    @Test
-    public void testStop() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.stop();
-            assertTrue(mPlayer.mStopCalled);
-        });
-    }
-
-    @Test
-    public void testSkipToNextItem() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.skipToNextItem();
-            assertTrue(mPlayer.mSkipToNextCalled);
-        });
-    }
-
-    @Ignore
-    @Test
-    public void testSkipToPreviousItem() throws Exception {
-        sHandler.postAndSync(() -> {
-            mSession.skipToPreviousItem();
-            assertTrue(mPlayer.mSkipToPreviousCalled);
-        });
-    }
-
-    @Ignore
-    @Test
-    public void testSetPlaylist() throws Exception {
-        final List<MediaItem2> playlist = new ArrayList<>();
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaylistChanged(List<MediaItem2> givenList) {
-                assertMediaItemListEquals(playlist, givenList);
-                latch.countDown();
-            }
-        };
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        mSession.setPlaylist(playlist);
-
-        assertTrue(mPlayer.mSetPlaylistCalled);
-        assertMediaItemListEquals(playlist, mPlayer.mPlaylist);
-        assertMediaItemListEquals(playlist, mSession.getPlaylist());
-
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertMediaItemListEquals(playlist, controller.getPlaylist());
-    }
-
-    @Ignore
-    @Test
-    public void testSetPlaylistParams() throws Exception {
-        final PlaylistParams params = new PlaylistParams(mContext,
-                PlaylistParams.REPEAT_MODE_ALL,
-                PlaylistParams.SHUFFLE_MODE_ALL,
-                null /* PlaylistMetadata */);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onPlaylistParamsChanged(PlaylistParams givenParams) {
-                ensurePlaylistParamsModeEquals(params, givenParams);
-                latch.countDown();
-            }
-        };
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        mSession.setPlaylistParams(params);
-        assertTrue(mPlayer.mSetPlaylistParamsCalled);
-        ensurePlaylistParamsModeEquals(params, mPlayer.mPlaylistParams);
-        ensurePlaylistParamsModeEquals(params, mSession.getPlaylistParams());
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Ignore
-    @Test
-    public void testRegisterEventCallback() throws InterruptedException {
-        final int testWhat = 1001;
-        final MockPlayer player = new MockPlayer(0);
-        final CountDownLatch playbackLatch = new CountDownLatch(3);
-        final CountDownLatch errorLatch = new CountDownLatch(1);
-        // TODO: Uncomment or remove
-        /*
-        final PlayerEventCallback callback = new PlayerEventCallback() {
-            @Override
-            public void onPlaybackStateChanged(PlaybackState2 state) {
-                assertEquals(sHandler.getLooper(), Looper.myLooper());
-                switch ((int) playbackLatch.getCount()) {
-                    case 3:
-                        assertNull(state);
-                        break;
-                    case 2:
-                        assertNotNull(state);
-                        assertEquals(PlaybackState2.STATE_PLAYING, state.getState());
-                        break;
-                    case 1:
-                        assertNotNull(state);
-                        assertEquals(PlaybackState2.STATE_PAUSED, state.getState());
-                        break;
-                    case 0:
-                        fail();
-                }
-                playbackLatch.countDown();
-            }
-
-            @Override
-            public void onError(String mediaId, int what, int extra) {
-                assertEquals(testWhat, what);
-                errorLatch.countDown();
-            }
-        };
-        */
-        player.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PLAYING));
-        // EventCallback will be notified with the mPlayer's playback state (null)
-        // TODO: Uncomment or remove
-        //mSession.registerPlayerEventCallback(sHandlerExecutor, callback);
-        // When the player is set, EventCallback will be notified about the new player's state.
-        mSession.updatePlayer(player, null, null);
-        // When the player is set, EventCallback will be notified about the new player's state.
-        player.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PAUSED));
-        assertTrue(playbackLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        player.notifyError(testWhat);
-        assertTrue(errorLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testBadPlayer() throws InterruptedException {
-        // TODO(jaewan): Add equivalent tests again
-        final CountDownLatch latch = new CountDownLatch(4); // expected call + 1
-        final BadPlayer player = new BadPlayer(0);
-        // TODO: Uncomment or remove
-        /*
-        mSession.registerPlayerEventCallback(sHandlerExecutor, new PlayerEventCallback() {
-            @Override
-            public void onPlaybackStateChanged(PlaybackState2 state) {
-                // This will be called for every setPlayer() calls, but no more.
-                assertNull(state);
-                latch.countDown();
-            }
-        });
-        */
-        mSession.updatePlayer(player, null, null);
-        mSession.updatePlayer(mPlayer, null, null);
-        player.notifyPlaybackState(createPlaybackState(PlaybackState2.STATE_PAUSED));
-        assertFalse(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    private static class BadPlayer extends MockPlayer {
-        public BadPlayer(int count) {
-            super(count);
-        }
-
-        @Override
-        public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback listener) {
-            // No-op. This bad player will keep push notification to the listener that is previously
-            // registered by session.setPlayer().
-        }
-    }
-
-    @Test
-    public void testOnCommandCallback() throws InterruptedException {
-        final MockOnCommandCallback callback = new MockOnCommandCallback();
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mPlayer = new MockPlayer(1);
-            mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                    .setSessionCallback(sHandlerExecutor, callback).build();
-        });
-        MediaController2 controller = createController(mSession.getToken());
-        controller.pause();
-        assertFalse(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertFalse(mPlayer.mPauseCalled);
-        assertEquals(1, callback.commands.size());
-        assertEquals(MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE,
-                (long) callback.commands.get(0).getCommandCode());
-        controller.skipToNextItem();
-        assertTrue(mPlayer.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertTrue(mPlayer.mSkipToNextCalled);
-        assertFalse(mPlayer.mPauseCalled);
-        assertEquals(2, callback.commands.size());
-        assertEquals(MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM,
-                (long) callback.commands.get(1).getCommandCode());
-    }
-
-    @Test
-    public void testOnConnectCallback() throws InterruptedException {
-        final MockOnConnectCallback sessionCallback = new MockOnConnectCallback();
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer)
-                    .setSessionCallback(sHandlerExecutor, sessionCallback).build();
-        });
-        MediaController2 controller =
-                createController(mSession.getToken(), false, null);
-        assertNotNull(controller);
-        waitForConnect(controller, false);
-        waitForDisconnect(controller, true);
-    }
-
-    @Test
-    public void testSetCustomLayout() throws InterruptedException {
-        final List<CommandButton> buttons = new ArrayList<>();
-        buttons.add(new CommandButton.Builder(mContext)
-                .setCommand(new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PLAY))
-                .setDisplayName("button").build());
-        final CountDownLatch latch = new CountDownLatch(1);
-        final SessionCallback sessionCallback = new SessionCallback(mContext) {
-            @Override
-            public CommandGroup onConnect(MediaSession2 session,
-                    ControllerInfo controller) {
-                if (mContext.getPackageName().equals(controller.getPackageName())) {
-                    mSession.setCustomLayout(controller, buttons);
-                }
-                return super.onConnect(session, controller);
-            }
-        };
-
-        try (final MediaSession2 session = new MediaSession2.Builder(mContext)
-                .setPlayer(mPlayer)
-                .setId("testSetCustomLayout")
-                .setSessionCallback(sHandlerExecutor, sessionCallback)
-                .build()) {
-            if (mSession != null) {
-                mSession.close();
-                mSession = session;
-            }
-            final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-                @Override
-                public void onCustomLayoutChanged(List<CommandButton> layout) {
-                    assertEquals(layout.size(), buttons.size());
-                    for (int i = 0; i < layout.size(); i++) {
-                        assertEquals(layout.get(i).getCommand(), buttons.get(i).getCommand());
-                        assertEquals(layout.get(i).getDisplayName(),
-                                buttons.get(i).getDisplayName());
-                    }
-                    latch.countDown();
-                }
-            };
-            final MediaController2 controller =
-                    createController(session.getToken(), true, callback);
-            assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        }
-    }
-
-    @Test
-    public void testSetAllowedCommands() throws InterruptedException {
-        final CommandGroup commands = new CommandGroup(mContext);
-        commands.addCommand(new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PLAY));
-        commands.addCommand(new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE));
-        commands.addCommand(new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_STOP));
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onAllowedCommandsChanged(CommandGroup commandsOut) {
-                assertNotNull(commandsOut);
-                List<Command> expected = commands.getCommands();
-                List<Command> actual = commandsOut.getCommands();
-
-                assertNotNull(actual);
-                assertEquals(expected.size(), actual.size());
-                for (int i = 0; i < expected.size(); i++) {
-                    assertEquals(expected.get(i), actual.get(i));
-                }
-                latch.countDown();
-            }
-        };
-
-        final MediaController2 controller = createController(mSession.getToken(), true, callback);
-        ControllerInfo controllerInfo = getTestControllerInfo();
-        assertNotNull(controllerInfo);
-
-        mSession.setAllowedCommands(controllerInfo, commands);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testSendCustomAction() throws InterruptedException {
-        final Command testCommand =
-                new Command(mContext, MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE);
-        final Bundle testArgs = new Bundle();
-        testArgs.putString("args", "testSendCustomAction");
-
-        final CountDownLatch latch = new CountDownLatch(2);
-        final TestControllerCallbackInterface callback = new TestControllerCallbackInterface() {
-            @Override
-            public void onCustomCommand(Command command, Bundle args, ResultReceiver receiver) {
-                assertEquals(testCommand, command);
-                assertTrue(TestUtils.equals(testArgs, args));
-                assertNull(receiver);
-                latch.countDown();
-            }
-        };
-        final MediaController2 controller =
-                createController(mSession.getToken(), true, callback);
-        // TODO(jaewan): Test with multiple controllers
-        mSession.sendCustomCommand(testCommand, testArgs);
-
-        ControllerInfo controllerInfo = getTestControllerInfo();
-        assertNotNull(controllerInfo);
-        // TODO(jaewan): Test receivers as well.
-        mSession.sendCustomCommand(controllerInfo, testCommand, testArgs, null);
-        assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-    }
-
-    private ControllerInfo getTestControllerInfo() {
-        List<ControllerInfo> controllers = mSession.getConnectedControllers();
-        assertNotNull(controllers);
-        for (int i = 0; i < controllers.size(); i++) {
-            if (Process.myUid() == controllers.get(i).getUid()) {
-                return controllers.get(i);
-            }
-        }
-        fail("Failed to get test controller info");
-        return null;
-    }
-
-    public class MockOnConnectCallback extends SessionCallback {
-        public MockOnConnectCallback() {
-            super(mContext);
-        }
-
-        @Override
-        public MediaSession2.CommandGroup onConnect(MediaSession2 session,
-                ControllerInfo controllerInfo) {
-            if (Process.myUid() != controllerInfo.getUid()) {
-                return null;
-            }
-            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
-            assertEquals(Process.myUid(), controllerInfo.getUid());
-            assertFalse(controllerInfo.isTrusted());
-            // Reject all
-            return null;
-        }
-    }
-
-    public class MockOnCommandCallback extends SessionCallback {
-        public final ArrayList<MediaSession2.Command> commands = new ArrayList<>();
-
-        public MockOnCommandCallback() {
-            super(mContext);
-        }
-
-        @Override
-        public boolean onCommandRequest(MediaSession2 session, ControllerInfo controllerInfo,
-                MediaSession2.Command command) {
-            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
-            assertEquals(Process.myUid(), controllerInfo.getUid());
-            assertFalse(controllerInfo.isTrusted());
-            commands.add(command);
-            if (command.getCommandCode() == MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    private static void assertMediaItemListEquals(List<MediaItem2> a, List<MediaItem2> b) {
-        if (a == null || b == null) {
-            assertEquals(a, b);
-        }
-        assertEquals(a.size(), b.size());
-
-        for (int i = 0; i < a.size(); i++) {
-            MediaItem2 aItem = a.get(i);
-            MediaItem2 bItem = b.get(i);
-
-            if (aItem == null || bItem == null) {
-                assertEquals(aItem, bItem);
-                continue;
-            }
-
-            assertEquals(aItem.getMediaId(), bItem.getMediaId());
-            assertEquals(aItem.getFlags(), bItem.getFlags());
-            TestUtils.equals(aItem.getMetadata().toBundle(), bItem.getMetadata().toBundle());
-
-            // Note: Here it does not check whether DataSourceDesc are equal,
-            // since there DataSourceDec is not comparable.
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSession2TestBase.java b/packages/MediaComponents/test/src/android/media/MediaSession2TestBase.java
deleted file mode 100644
index 83706c0..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaSession2TestBase.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.content.Context;
-import android.media.MediaController2.ControllerCallback;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
-import android.os.Bundle;
-import android.os.HandlerThread;
-import android.os.ResultReceiver;
-import android.support.annotation.CallSuper;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.test.InstrumentationRegistry;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-/**
- * Base class for session test.
- */
-abstract class MediaSession2TestBase {
-    // Expected success
-    static final int WAIT_TIME_MS = 1000;
-
-    // Expected timeout
-    static final int TIMEOUT_MS = 500;
-
-    static TestUtils.SyncHandler sHandler;
-    static Executor sHandlerExecutor;
-
-    Context mContext;
-    private List<MediaController2> mControllers = new ArrayList<>();
-
-    interface TestControllerInterface {
-        ControllerCallback getCallback();
-    }
-
-    // Any change here should be also reflected to the TestControllerCallback and
-    // TestBrowserCallback
-    interface TestControllerCallbackInterface {
-        // Add methods in ControllerCallback that you want to test.
-        default void onPlaylistChanged(List<MediaItem2> playlist) {}
-        default void onPlaylistParamsChanged(MediaSession2.PlaylistParams params) {}
-        default void onPlaybackInfoChanged(MediaController2.PlaybackInfo info) {}
-        default void onPlaybackStateChanged(PlaybackState2 state) {}
-        default void onCustomLayoutChanged(List<CommandButton> layout) {}
-        default void onAllowedCommandsChanged(CommandGroup commands) {}
-        default void onCustomCommand(Command command, Bundle args, ResultReceiver receiver) {}
-    }
-
-    interface WaitForConnectionInterface {
-        void waitForConnect(boolean expect) throws InterruptedException;
-        void waitForDisconnect(boolean expect) throws InterruptedException;
-    }
-
-    @BeforeClass
-    public static void setUpThread() {
-        if (sHandler == null) {
-            HandlerThread handlerThread = new HandlerThread("MediaSession2TestBase");
-            handlerThread.start();
-            sHandler = new TestUtils.SyncHandler(handlerThread.getLooper());
-            sHandlerExecutor = (runnable) -> {
-                sHandler.post(runnable);
-            };
-        }
-    }
-
-    @AfterClass
-    public static void cleanUpThread() {
-        if (sHandler != null) {
-            sHandler.getLooper().quitSafely();
-            sHandler = null;
-            sHandlerExecutor = null;
-        }
-    }
-
-    @CallSuper
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @CallSuper
-    public void cleanUp() throws Exception {
-        for (int i = 0; i < mControllers.size(); i++) {
-            mControllers.get(i).close();
-        }
-    }
-
-    /**
-     * Creates a {@link android.media.session.PlaybackState} with the given state.
-     *
-     * @param state one of the PlaybackState.STATE_xxx.
-     * @return a PlaybackState
-     */
-    public PlaybackState2 createPlaybackState(int state) {
-        return new PlaybackState2(mContext, state, 0, 0, 1.0f, 0, 0);
-    }
-
-    final MediaController2 createController(SessionToken2 token) throws InterruptedException {
-        return createController(token, true, null);
-    }
-
-    final MediaController2 createController(@NonNull SessionToken2 token,
-            boolean waitForConnect, @Nullable TestControllerCallbackInterface callback)
-            throws InterruptedException {
-        TestControllerInterface instance = onCreateController(token, callback);
-        if (!(instance instanceof MediaController2)) {
-            throw new RuntimeException("Test has a bug. Expected MediaController2 but returned "
-                    + instance);
-        }
-        MediaController2 controller = (MediaController2) instance;
-        mControllers.add(controller);
-        if (waitForConnect) {
-            waitForConnect(controller, true);
-        }
-        return controller;
-    }
-
-    private static WaitForConnectionInterface getWaitForConnectionInterface(
-            MediaController2 controller) {
-        if (!(controller instanceof TestControllerInterface)) {
-            throw new RuntimeException("Test has a bug. Expected controller implemented"
-                    + " TestControllerInterface but got " + controller);
-        }
-        ControllerCallback callback = ((TestControllerInterface) controller).getCallback();
-        if (!(callback instanceof WaitForConnectionInterface)) {
-            throw new RuntimeException("Test has a bug. Expected controller with callback "
-                    + " implemented WaitForConnectionInterface but got " + controller);
-        }
-        return (WaitForConnectionInterface) callback;
-    }
-
-    public static void waitForConnect(MediaController2 controller, boolean expected)
-            throws InterruptedException {
-        getWaitForConnectionInterface(controller).waitForConnect(expected);
-    }
-
-    public static void waitForDisconnect(MediaController2 controller, boolean expected)
-            throws InterruptedException {
-        getWaitForConnectionInterface(controller).waitForDisconnect(expected);
-    }
-
-    TestControllerInterface onCreateController(@NonNull SessionToken2 token,
-            @Nullable TestControllerCallbackInterface callback) {
-        if (callback == null) {
-            callback = new TestControllerCallbackInterface() {};
-        }
-        return new TestMediaController(mContext, token, new TestControllerCallback(callback));
-    }
-
-    public static class TestControllerCallback extends MediaController2.ControllerCallback
-            implements WaitForConnectionInterface {
-        public final TestControllerCallbackInterface mCallbackProxy;
-        public final CountDownLatch connectLatch = new CountDownLatch(1);
-        public final CountDownLatch disconnectLatch = new CountDownLatch(1);
-
-        TestControllerCallback(@NonNull TestControllerCallbackInterface callbackProxy) {
-            if (callbackProxy == null) {
-                throw new IllegalArgumentException("Callback proxy shouldn't be null. Test bug");
-            }
-            mCallbackProxy = callbackProxy;
-        }
-
-        @CallSuper
-        @Override
-        public void onConnected(MediaController2 controller, CommandGroup commands) {
-            connectLatch.countDown();
-        }
-
-        @CallSuper
-        @Override
-        public void onDisconnected(MediaController2 controller) {
-            disconnectLatch.countDown();
-        }
-
-        @Override
-        public void onPlaybackStateChanged(MediaController2 controller, PlaybackState2 state) {
-            mCallbackProxy.onPlaybackStateChanged(state);
-        }
-
-        @Override
-        public void onCustomCommand(MediaController2 controller, Command command, Bundle args,
-                ResultReceiver receiver) {
-            mCallbackProxy.onCustomCommand(command, args, receiver);
-        }
-
-        @Override
-        public void waitForConnect(boolean expect) throws InterruptedException {
-            if (expect) {
-                assertTrue(connectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            } else {
-                assertFalse(connectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-
-        @Override
-        public void waitForDisconnect(boolean expect) throws InterruptedException {
-            if (expect) {
-                assertTrue(disconnectLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            } else {
-                assertFalse(disconnectLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-
-        @Override
-        public void onPlaylistChanged(MediaController2 controller, List<MediaItem2> params) {
-            mCallbackProxy.onPlaylistChanged(params);
-        }
-
-        @Override
-        public void onPlaylistParamsChanged(MediaController2 controller,
-                MediaSession2.PlaylistParams params) {
-            mCallbackProxy.onPlaylistParamsChanged(params);
-        }
-
-        @Override
-        public void onPlaybackInfoChanged(MediaController2 controller,
-                MediaController2.PlaybackInfo info) {
-            mCallbackProxy.onPlaybackInfoChanged(info);
-        }
-
-        @Override
-        public void onCustomLayoutChanged(MediaController2 controller, List<CommandButton> layout) {
-            mCallbackProxy.onCustomLayoutChanged(layout);
-        }
-
-        @Override
-        public void onAllowedCommandsChanged(MediaController2 controller, CommandGroup commands) {
-            mCallbackProxy.onAllowedCommandsChanged(commands);
-        }
-    }
-
-    public class TestMediaController extends MediaController2 implements TestControllerInterface {
-        private final ControllerCallback mCallback;
-
-        public TestMediaController(@NonNull Context context, @NonNull SessionToken2 token,
-                @NonNull ControllerCallback callback) {
-            super(context, token, sHandlerExecutor, callback);
-            mCallback = callback;
-        }
-
-        @Override
-        public ControllerCallback getCallback() {
-            return mCallback;
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSession2_PermissionTest.java b/packages/MediaComponents/test/src/android/media/MediaSession2_PermissionTest.java
deleted file mode 100644
index ca36513..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaSession2_PermissionTest.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_FAST_FORWARD;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_PLAY;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_REWIND;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SEEK_TO;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SET_VOLUME;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_STOP;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_MEDIA_ID;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_URI;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_MEDIA_ID;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_SEARCH;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_URI;
-import static android.media.MediaSession2.ControllerInfo;
-import static android.media.MediaSession2.PlaylistParams;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.SessionCallback;
-import android.net.Uri;
-import android.os.Process;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/**
- * Tests whether {@link MediaSession2} receives commands that hasn't allowed.
- */
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class MediaSession2_PermissionTest extends MediaSession2TestBase {
-    private static final String SESSION_ID = "MediaSession2Test_permission";
-
-    private MockPlayer mPlayer;
-    private MediaSession2 mSession;
-    private MediaSession2.SessionCallback mCallback;
-
-    private MediaSession2 matchesSession() {
-        return argThat((session) -> session == mSession);
-    }
-
-    private static ControllerInfo matchesCaller() {
-        return argThat((controllerInfo) -> controllerInfo.getUid() == Process.myUid());
-    }
-
-    private static Command matches(final int commandCode) {
-        return argThat((command) -> command.getCommandCode() == commandCode);
-    }
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @After
-    @Override
-    public void cleanUp() throws Exception {
-        super.cleanUp();
-        if (mSession != null) {
-            mSession.close();
-            mSession = null;
-        }
-        mPlayer = null;
-        mCallback = null;
-    }
-
-    private MediaSession2 createSessionWithAllowedActions(CommandGroup commands) {
-        mPlayer = new MockPlayer(0);
-        if (commands == null) {
-            commands = new CommandGroup(mContext);
-        }
-        mCallback = mock(SessionCallback.class);
-        when(mCallback.onConnect(any(), any())).thenReturn(commands);
-        if (mSession != null) {
-            mSession.close();
-        }
-        mSession = new MediaSession2.Builder(mContext).setPlayer(mPlayer).setId(SESSION_ID)
-                .setSessionCallback(sHandlerExecutor, mCallback).build();
-        return mSession;
-    }
-
-    private CommandGroup createCommandGroupWith(int commandCode) {
-        CommandGroup commands = new CommandGroup(mContext);
-        commands.addCommand(new Command(mContext, commandCode));
-        return commands;
-    }
-
-    private CommandGroup createCommandGroupWithout(int commandCode) {
-        CommandGroup commands = new CommandGroup(mContext);
-        commands.addAllPredefinedCommands();
-        commands.removeCommand(new Command(mContext, commandCode));
-        return commands;
-    }
-
-    @Test
-    public void testPlay() throws InterruptedException {
-        createSessionWithAllowedActions(createCommandGroupWith(COMMAND_CODE_PLAYBACK_PLAY));
-        createController(mSession.getToken()).play();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_PLAY));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_PLAY));
-        createController(mSession.getToken()).play();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testPause() throws InterruptedException {
-        createSessionWithAllowedActions(createCommandGroupWith(COMMAND_CODE_PLAYBACK_PAUSE));
-        createController(mSession.getToken()).pause();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_PAUSE));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_PAUSE));
-        createController(mSession.getToken()).pause();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testStop() throws InterruptedException {
-        createSessionWithAllowedActions(createCommandGroupWith(COMMAND_CODE_PLAYBACK_STOP));
-        createController(mSession.getToken()).stop();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_STOP));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_STOP));
-        createController(mSession.getToken()).stop();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testSkipToNext() throws InterruptedException {
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM));
-        createController(mSession.getToken()).skipToNextItem();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM));
-        createController(mSession.getToken()).skipToNextItem();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testSkipToPrevious() throws InterruptedException {
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM));
-        createController(mSession.getToken()).skipToPreviousItem();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM));
-        createController(mSession.getToken()).skipToPreviousItem();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testFastForward() throws InterruptedException {
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_FAST_FORWARD));
-        createController(mSession.getToken()).fastForward();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_FAST_FORWARD));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_FAST_FORWARD));
-        createController(mSession.getToken()).fastForward();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testRewind() throws InterruptedException {
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_REWIND));
-        createController(mSession.getToken()).rewind();
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_REWIND));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_REWIND));
-        createController(mSession.getToken()).rewind();
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testSeekTo() throws InterruptedException {
-        final long position = 10;
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SEEK_TO));
-        createController(mSession.getToken()).seekTo(position);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_SEEK_TO));
-
-        createSessionWithAllowedActions(createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SEEK_TO));
-        createController(mSession.getToken()).seekTo(position);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    // TODO(jaewan): Uncomment when we implement skipToPlaylistItem()
-    /*
-    @Test
-    public void testSkipToPlaylistItem() throws InterruptedException {
-        final Uri uri = Uri.parse("set://current.playlist.item");
-        final DataSourceDesc dsd = new DataSourceDesc.Builder()
-                .setDataSource(mContext, uri).build();
-        final MediaItem2 item = new MediaItem2.Builder(mContext, MediaItem2.FLAG_PLAYABLE)
-                .setDataSourceDesc(dsd).build();
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM));
-        createController(mSession.getToken()).skipToPlaylistItem(item);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(matchesCaller(),
-                matches(COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM));
-        createController(mSession.getToken()).skipToPlaylistItem(item);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any());
-    }
-    */
-
-    @Test
-    public void testSetPlaylistParams() throws InterruptedException {
-        final PlaylistParams param = new PlaylistParams(mContext,
-                PlaylistParams.REPEAT_MODE_ALL, PlaylistParams.SHUFFLE_MODE_ALL, null);
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS));
-        createController(mSession.getToken()).setPlaylistParams(param);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(),
-                matches(COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS));
-        createController(mSession.getToken()).setPlaylistParams(param);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testSetVolume() throws InterruptedException {
-        createSessionWithAllowedActions(createCommandGroupWith(COMMAND_CODE_PLAYBACK_SET_VOLUME));
-        createController(mSession.getToken()).setVolumeTo(0, 0);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onCommandRequest(
-                matchesSession(), matchesCaller(), matches(COMMAND_CODE_PLAYBACK_SET_VOLUME));
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAYBACK_SET_VOLUME));
-        createController(mSession.getToken()).setVolumeTo(0, 0);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onCommandRequest(any(), any(), any());
-    }
-
-    @Test
-    public void testPlayFromMediaId() throws InterruptedException {
-        final String mediaId = "testPlayFromMediaId";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAY_FROM_MEDIA_ID));
-        createController(mSession.getToken()).playFromMediaId(mediaId, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPlayFromMediaId(
-                matchesSession(), matchesCaller(), eq(mediaId), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAY_FROM_MEDIA_ID));
-        createController(mSession.getToken()).playFromMediaId(mediaId, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPlayFromMediaId(
-                any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPlayFromUri() throws InterruptedException {
-        final Uri uri = Uri.parse("play://from.uri");
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAY_FROM_URI));
-        createController(mSession.getToken()).playFromUri(uri, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPlayFromUri(
-                matchesSession(), matchesCaller(), eq(uri), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAY_FROM_URI));
-        createController(mSession.getToken()).playFromUri(uri, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPlayFromUri(any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPlayFromSearch() throws InterruptedException {
-        final String query = "testPlayFromSearch";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PLAY_FROM_SEARCH));
-        createController(mSession.getToken()).playFromSearch(query, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPlayFromSearch(
-                matchesSession(), matchesCaller(), eq(query), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PLAY_FROM_SEARCH));
-        createController(mSession.getToken()).playFromSearch(query, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPlayFromSearch(any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPrepareFromMediaId() throws InterruptedException {
-        final String mediaId = "testPrepareFromMediaId";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PREPARE_FROM_MEDIA_ID));
-        createController(mSession.getToken()).prepareFromMediaId(mediaId, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPrepareFromMediaId(
-                matchesSession(), matchesCaller(), eq(mediaId), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PREPARE_FROM_MEDIA_ID));
-        createController(mSession.getToken()).prepareFromMediaId(mediaId, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPrepareFromMediaId(
-                any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPrepareFromUri() throws InterruptedException {
-        final Uri uri = Uri.parse("prepare://from.uri");
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PREPARE_FROM_URI));
-        createController(mSession.getToken()).prepareFromUri(uri, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPrepareFromUri(
-                matchesSession(), matchesCaller(), eq(uri), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PREPARE_FROM_URI));
-        createController(mSession.getToken()).prepareFromUri(uri, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPrepareFromUri(any(), any(), any(), any());
-    }
-
-    @Test
-    public void testPrepareFromSearch() throws InterruptedException {
-        final String query = "testPrepareFromSearch";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PREPARE_FROM_SEARCH));
-        createController(mSession.getToken()).prepareFromSearch(query, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPrepareFromSearch(
-                matchesSession(), matchesCaller(), eq(query), isNull());
-
-        createSessionWithAllowedActions(
-                createCommandGroupWithout(COMMAND_CODE_PREPARE_FROM_SEARCH));
-        createController(mSession.getToken()).prepareFromSearch(query, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPrepareFromSearch(
-                any(), any(), any(), any());
-    }
-
-    @Test
-    public void testChangingPermissionWithSetAllowedCommands() throws InterruptedException {
-        final String query = "testChangingPermissionWithSetAllowedCommands";
-        createSessionWithAllowedActions(
-                createCommandGroupWith(COMMAND_CODE_PREPARE_FROM_SEARCH));
-
-        TestControllerCallbackInterface controllerCallback =
-                mock(TestControllerCallbackInterface.class);
-        MediaController2 controller =
-                createController(mSession.getToken(), true, controllerCallback);
-
-        controller.prepareFromSearch(query, null);
-        verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()).onPrepareFromSearch(
-                matchesSession(), matchesCaller(), eq(query), isNull());
-        clearInvocations(mCallback);
-
-        // Change allowed commands.
-        mSession.setAllowedCommands(getTestControllerInfo(),
-                createCommandGroupWithout(COMMAND_CODE_PREPARE_FROM_SEARCH));
-        verify(controllerCallback, timeout(TIMEOUT_MS).atLeastOnce())
-                .onAllowedCommandsChanged(any());
-
-        controller.prepareFromSearch(query, null);
-        verify(mCallback, after(WAIT_TIME_MS).never()).onPrepareFromSearch(
-                any(), any(), any(), any());
-    }
-
-    private ControllerInfo getTestControllerInfo() {
-        List<ControllerInfo> controllers = mSession.getConnectedControllers();
-        assertNotNull(controllers);
-        for (int i = 0; i < controllers.size(); i++) {
-            if (Process.myUid() == controllers.get(i).getUid()) {
-                return controllers.get(i);
-            }
-        }
-        fail("Failed to get test controller info");
-        return null;
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java b/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java
deleted file mode 100644
index 17b200f..0000000
--- a/packages/MediaComponents/test/src/android/media/MediaSessionManager_MediaSession2.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.content.Context;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.SessionCallback;
-import android.media.session.MediaSessionManager;
-import android.media.session.MediaSessionManager.OnSessionTokensChangedListener;
-import android.media.session.PlaybackState;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.UUID;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests {@link MediaSessionManager} with {@link MediaSession2} specific APIs.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaSessionManager_MediaSession2 extends MediaSession2TestBase {
-    private static final String TAG = "MediaSessionManager_MediaSession2";
-
-    private MediaSessionManager mManager;
-    private MediaSession2 mSession;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mManager = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
-
-        // Specify TAG here so {@link MediaSession2.getInstance()} doesn't complaint about
-        // per test thread differs across the {@link MediaSession2} with the same TAG.
-        final MockPlayer player = new MockPlayer(1);
-        mSession = new MediaSession2.Builder(mContext)
-                .setPlayer(player)
-                .setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) { })
-                .setId(TAG)
-                .build();
-        ensureChangeInSession();
-    }
-
-    @After
-    @Override
-    public void cleanUp() throws Exception {
-        super.cleanUp();
-        sHandler.removeCallbacksAndMessages(null);
-        mSession.close();
-    }
-
-    // TODO(jaewan): Make this host-side test to see per-user behavior.
-    @Ignore
-    @Test
-    public void testGetMediaSession2Tokens_hasMediaController() throws InterruptedException {
-        final MockPlayer player = (MockPlayer) mSession.getPlayer();
-        player.notifyPlaybackState(createPlaybackState(PlaybackState.STATE_STOPPED));
-
-        MediaController2 controller = null;
-        List<SessionToken2> tokens = mManager.getActiveSessionTokens();
-        assertNotNull(tokens);
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (mContext.getPackageName().equals(token.getPackageName())
-                    && TAG.equals(token.getId())) {
-                assertNull(controller);
-                controller = createController(token);
-            }
-        }
-        assertNotNull(controller);
-
-        // Test if the found controller is correct one.
-        assertEquals(PlaybackState.STATE_STOPPED, controller.getPlaybackState().getState());
-        controller.play();
-
-        assertTrue(player.mCountDownLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-        assertTrue(player.mPlayCalled);
-    }
-
-    /**
-     * Test if server recognizes a session even if the session refuses the connection from server.
-     *
-     * @throws InterruptedException
-     */
-    @Test
-    public void testGetSessionTokens_sessionRejected() throws InterruptedException {
-        sHandler.postAndSync(() -> {
-            mSession.close();
-            mSession = new MediaSession2.Builder(mContext).setPlayer(new MockPlayer(0))
-                    .setId(TAG).setSessionCallback(sHandlerExecutor, new SessionCallback(mContext) {
-                        @Override
-                        public MediaSession2.CommandGroup onConnect(
-                                MediaSession2 session, ControllerInfo controller) {
-                            // Reject all connection request.
-                            return null;
-                        }
-                    }).build();
-        });
-        ensureChangeInSession();
-
-        boolean foundSession = false;
-        List<SessionToken2> tokens = mManager.getActiveSessionTokens();
-        assertNotNull(tokens);
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (mContext.getPackageName().equals(token.getPackageName())
-                    && TAG.equals(token.getId())) {
-                assertFalse(foundSession);
-                foundSession = true;
-            }
-        }
-        assertTrue(foundSession);
-    }
-
-    @Test
-    public void testGetMediaSession2Tokens_playerRemoved() throws InterruptedException {
-        // Release
-        sHandler.postAndSync(() -> {
-            mSession.close();
-        });
-        ensureChangeInSession();
-
-        // When the mSession's player becomes null, it should lose binder connection between server.
-        // So server will forget the session.
-        List<SessionToken2> tokens = mManager.getActiveSessionTokens();
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            assertFalse(mContext.getPackageName().equals(token.getPackageName())
-                    && TAG.equals(token.getId()));
-        }
-    }
-
-    @Test
-    public void testGetMediaSessionService2Token() throws InterruptedException {
-        boolean foundTestSessionService = false;
-        boolean foundTestLibraryService = false;
-        List<SessionToken2> tokens = mManager.getSessionServiceTokens();
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (mContext.getPackageName().equals(token.getPackageName())
-                    && MockMediaSessionService2.ID.equals(token.getId())) {
-                assertFalse(foundTestSessionService);
-                assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-                foundTestSessionService = true;
-            } else if (mContext.getPackageName().equals(token.getPackageName())
-                    && MockMediaLibraryService2.ID.equals(token.getId())) {
-                assertFalse(foundTestLibraryService);
-                assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, token.getType());
-                foundTestLibraryService = true;
-            }
-        }
-        assertTrue(foundTestSessionService);
-        assertTrue(foundTestLibraryService);
-    }
-
-    @Test
-    public void testGetAllSessionTokens() throws InterruptedException {
-        boolean foundTestSession = false;
-        boolean foundTestSessionService = false;
-        boolean foundTestLibraryService = false;
-        List<SessionToken2> tokens = mManager.getAllSessionTokens();
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (!mContext.getPackageName().equals(token.getPackageName())) {
-                continue;
-            }
-            switch (token.getId()) {
-                case TAG:
-                    assertFalse(foundTestSession);
-                    foundTestSession = true;
-                    break;
-                case MockMediaSessionService2.ID:
-                    assertFalse(foundTestSessionService);
-                    foundTestSessionService = true;
-                    assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-                    break;
-                case MockMediaLibraryService2.ID:
-                    assertFalse(foundTestLibraryService);
-                    assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, token.getType());
-                    foundTestLibraryService = true;
-                    break;
-                default:
-                    fail("Unexpected session " + token + " exists in the package");
-            }
-        }
-        assertTrue(foundTestSession);
-        assertTrue(foundTestSessionService);
-        assertTrue(foundTestLibraryService);
-    }
-
-    @Test
-    public void testAddOnSessionTokensChangedListener() throws InterruptedException {
-        TokensChangedListener listener = new TokensChangedListener();
-        mManager.addOnSessionTokensChangedListener(sHandlerExecutor, listener);
-
-        listener.reset();
-        MediaSession2 session1 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertTrue(listener.await());
-        assertTrue(listener.findToken(session1.getToken()));
-
-        listener.reset();
-        session1.close();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-
-        listener.reset();
-        MediaSession2 session2 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-        assertTrue(listener.findToken(session2.getToken()));
-
-        listener.reset();
-        MediaSession2 session3 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-        assertTrue(listener.findToken(session2.getToken()));
-        assertTrue(listener.findToken(session3.getToken()));
-
-        listener.reset();
-        session2.close();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-        assertFalse(listener.findToken(session2.getToken()));
-        assertTrue(listener.findToken(session3.getToken()));
-
-        listener.reset();
-        session3.close();
-        assertTrue(listener.await());
-        assertFalse(listener.findToken(session1.getToken()));
-        assertFalse(listener.findToken(session2.getToken()));
-        assertFalse(listener.findToken(session3.getToken()));
-
-        mManager.removeOnSessionTokensChangedListener(listener);
-    }
-
-    @Test
-    public void testRemoveOnSessionTokensChangedListener() throws InterruptedException {
-        TokensChangedListener listener = new TokensChangedListener();
-        mManager.addOnSessionTokensChangedListener(sHandlerExecutor, listener);
-
-        listener.reset();
-        MediaSession2 session1 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertTrue(listener.await());
-
-        mManager.removeOnSessionTokensChangedListener(listener);
-
-        listener.reset();
-        session1.close();
-        assertFalse(listener.await());
-
-        listener.reset();
-        MediaSession2 session2 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertFalse(listener.await());
-
-        listener.reset();
-        MediaSession2 session3 = new MediaSession2.Builder(mContext)
-                .setPlayer(new MockPlayer(0))
-                .setId(UUID.randomUUID().toString())
-                .build();
-        assertFalse(listener.await());
-
-        listener.reset();
-        session2.close();
-        assertFalse(listener.await());
-
-        listener.reset();
-        session3.close();
-        assertFalse(listener.await());
-    }
-
-    // Ensures if the session creation/release is notified to the server.
-    private void ensureChangeInSession() throws InterruptedException {
-        // TODO(jaewan): Wait by listener.
-        Thread.sleep(WAIT_TIME_MS);
-    }
-
-    private class TokensChangedListener implements OnSessionTokensChangedListener {
-        private CountDownLatch mLatch;
-        private List<SessionToken2> mTokens;
-
-        private void reset() {
-            mLatch = new CountDownLatch(1);
-            mTokens = null;
-        }
-
-        private boolean await() throws InterruptedException {
-            return mLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        }
-
-        private boolean findToken(SessionToken2 token) {
-            return mTokens.contains(token);
-        }
-
-        @Override
-        public void onSessionTokensChanged(List<SessionToken2> tokens) {
-            mTokens = tokens;
-            mLatch.countDown();
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MockActivity.java b/packages/MediaComponents/test/src/android/media/MockActivity.java
deleted file mode 100644
index 4627530..0000000
--- a/packages/MediaComponents/test/src/android/media/MockActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.app.Activity;
-
-public class MockActivity extends Activity {
-}
diff --git a/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java b/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
deleted file mode 100644
index df516c5..0000000
--- a/packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
-* Copyright 2018 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package android.media;
-
-import static junit.framework.Assert.fail;
-
-import static org.junit.Assert.assertEquals;
-
-import android.content.Context;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
-import android.media.TestServiceRegistry.SessionCallbackProxy;
-import android.media.TestUtils.SyncHandler;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.util.ArrayList;
-import java.util.List;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * Mock implementation of {@link MediaLibraryService2} for testing.
- */
-public class MockMediaLibraryService2 extends MediaLibraryService2 {
-    // Keep in sync with the AndroidManifest.xml
-    public static final String ID = "TestLibrary";
-
-    public static final String ROOT_ID = "rootId";
-    public static final Bundle EXTRAS = new Bundle();
-
-    public static final String MEDIA_ID_GET_ITEM = "media_id_get_item";
-
-    public static final String PARENT_ID = "parent_id";
-    public static final String PARENT_ID_NO_CHILDREN = "parent_id_no_children";
-    public static final String PARENT_ID_ERROR = "parent_id_error";
-
-    public static final List<MediaItem2> GET_CHILDREN_RESULT = new ArrayList<>();
-    public static final int CHILDREN_COUNT = 100;
-
-    public static final String SEARCH_QUERY = "search_query";
-    public static final String SEARCH_QUERY_TAKES_TIME = "search_query_takes_time";
-    public static final int SEARCH_TIME_IN_MS = 5000;
-    public static final String SEARCH_QUERY_EMPTY_RESULT = "search_query_empty_result";
-
-    public static final List<MediaItem2> SEARCH_RESULT = new ArrayList<>();
-    public static final int SEARCH_RESULT_COUNT = 50;
-
-    private static final DataSourceDesc DATA_SOURCE_DESC =
-            new DataSourceDesc.Builder().setDataSource(new FileDescriptor()).build();
-
-    private static final String TAG = "MockMediaLibrarySvc2";
-
-    static {
-        EXTRAS.putString(ROOT_ID, ROOT_ID);
-    }
-    @GuardedBy("MockMediaLibraryService2.class")
-    private static SessionToken2 sToken;
-
-    private MediaLibrarySession mSession;
-
-    public MockMediaLibraryService2() {
-        super();
-        GET_CHILDREN_RESULT.clear();
-        String getChildrenMediaIdPrefix = "get_children_media_id_";
-        for (int i = 0; i < CHILDREN_COUNT; i++) {
-            GET_CHILDREN_RESULT.add(createMediaItem(getChildrenMediaIdPrefix + i));
-        }
-
-        SEARCH_RESULT.clear();
-        String getSearchResultMediaIdPrefix = "get_search_result_media_id_";
-        for (int i = 0; i < SEARCH_RESULT_COUNT; i++) {
-            SEARCH_RESULT.add(createMediaItem(getSearchResultMediaIdPrefix + i));
-        }
-    }
-
-    @Override
-    public void onCreate() {
-        TestServiceRegistry.getInstance().setServiceInstance(this);
-        super.onCreate();
-    }
-
-    @Override
-    public MediaLibrarySession onCreateSession(String sessionId) {
-        final MockPlayer player = new MockPlayer(1);
-        final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler();
-        final Executor executor = (runnable) -> handler.post(runnable);
-        SessionCallbackProxy sessionCallbackProxy = TestServiceRegistry.getInstance()
-                .getSessionCallbackProxy();
-        if (sessionCallbackProxy == null) {
-            // Ensures non-null
-            sessionCallbackProxy = new SessionCallbackProxy(this) {};
-        }
-        TestLibrarySessionCallback callback =
-                new TestLibrarySessionCallback(sessionCallbackProxy);
-        mSession = new MediaLibrarySession.Builder(MockMediaLibraryService2.this, executor,
-                callback).setPlayer(player).setId(sessionId).build();
-        return mSession;
-    }
-
-    @Override
-    public void onDestroy() {
-        TestServiceRegistry.getInstance().cleanUp();
-        super.onDestroy();
-    }
-
-    public static SessionToken2 getToken(Context context) {
-        synchronized (MockMediaLibraryService2.class) {
-            if (sToken == null) {
-                sToken = new SessionToken2(context, context.getPackageName(),
-                        MockMediaLibraryService2.class.getName());
-                assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, sToken.getType());
-            }
-            return sToken;
-        }
-    }
-
-    private class TestLibrarySessionCallback extends MediaLibrarySessionCallback {
-        private final SessionCallbackProxy mCallbackProxy;
-
-        public TestLibrarySessionCallback(SessionCallbackProxy callbackProxy) {
-            super(MockMediaLibraryService2.this);
-            mCallbackProxy = callbackProxy;
-        }
-
-        @Override
-        public CommandGroup onConnect(@NonNull MediaSession2 session,
-                @NonNull ControllerInfo controller) {
-            return mCallbackProxy.onConnect(session, controller);
-        }
-
-        @Override
-        public LibraryRoot onGetLibraryRoot(MediaLibrarySession session, ControllerInfo controller,
-                Bundle rootHints) {
-            return new LibraryRoot(MockMediaLibraryService2.this, ROOT_ID, EXTRAS);
-        }
-
-        @Override
-        public MediaItem2 onGetItem(MediaLibrarySession session, ControllerInfo controller,
-                String mediaId) {
-            if (MEDIA_ID_GET_ITEM.equals(mediaId)) {
-                return createMediaItem(mediaId);
-            } else {
-                return null;
-            }
-        }
-
-        @Override
-        public List<MediaItem2> onGetChildren(MediaLibrarySession session,
-                ControllerInfo controller, String parentId, int page, int pageSize, Bundle extras) {
-            if (PARENT_ID.equals(parentId)) {
-                return getPaginatedResult(GET_CHILDREN_RESULT, page, pageSize);
-            } else if (PARENT_ID_ERROR.equals(parentId)) {
-                return null;
-            }
-            // Includes the case of PARENT_ID_NO_CHILDREN.
-            return new ArrayList<>();
-        }
-
-        @Override
-        public void onSearch(MediaLibrarySession session, ControllerInfo controllerInfo,
-                String query, Bundle extras) {
-            if (SEARCH_QUERY.equals(query)) {
-                mSession.notifySearchResultChanged(controllerInfo, query, SEARCH_RESULT_COUNT,
-                        extras);
-            } else if (SEARCH_QUERY_TAKES_TIME.equals(query)) {
-                // Searching takes some time. Notify after 5 seconds.
-                Executors.newSingleThreadScheduledExecutor().schedule(new Runnable() {
-                    @Override
-                    public void run() {
-                        mSession.notifySearchResultChanged(
-                                controllerInfo, query, SEARCH_RESULT_COUNT, extras);
-                    }
-                }, SEARCH_TIME_IN_MS, TimeUnit.MILLISECONDS);
-            } else if (SEARCH_QUERY_EMPTY_RESULT.equals(query)) {
-                mSession.notifySearchResultChanged(controllerInfo, query, 0, extras);
-            } else {
-                // TODO: For the error case, how should we notify the browser?
-            }
-        }
-
-        @Override
-        public List<MediaItem2> onGetSearchResult(MediaLibrarySession session,
-                ControllerInfo controllerInfo, String query, int page, int pageSize,
-                Bundle extras) {
-            if (SEARCH_QUERY.equals(query)) {
-                return getPaginatedResult(SEARCH_RESULT, page, pageSize);
-            } else {
-                return null;
-            }
-        }
-
-        @Override
-        public void onSubscribe(@NonNull MediaLibrarySession session,
-                @NonNull ControllerInfo controller, @NonNull String parentId,
-                @Nullable Bundle extras) {
-            mCallbackProxy.onSubscribe(session, controller, parentId, extras);
-        }
-
-        @Override
-        public void onUnsubscribe(@NonNull MediaLibrarySession session,
-                @NonNull ControllerInfo controller, String parentId) {
-            mCallbackProxy.onUnsubscribe(session, controller, parentId);
-        }
-    }
-
-    private List<MediaItem2> getPaginatedResult(List<MediaItem2> items, int page, int pageSize) {
-        if (items == null) {
-            return null;
-        } else if (items.size() == 0) {
-            return new ArrayList<>();
-        }
-
-        final int totalItemCount = items.size();
-        int fromIndex = (page - 1) * pageSize;
-        int toIndex = Math.min(page * pageSize, totalItemCount);
-
-        List<MediaItem2> paginatedResult = new ArrayList<>();
-        try {
-            // The case of (fromIndex >= totalItemCount) will throw exception below.
-            paginatedResult = items.subList(fromIndex, toIndex);
-        } catch (IndexOutOfBoundsException | IllegalArgumentException ex) {
-            Log.d(TAG, "Result is empty for given pagination arguments: totalItemCount="
-                    + totalItemCount + ", page=" + page + ", pageSize=" + pageSize, ex);
-        }
-        return paginatedResult;
-    }
-
-    private MediaItem2 createMediaItem(String mediaId) {
-        Context context = MockMediaLibraryService2.this;
-        return new MediaItem2.Builder(context, 0 /* Flags */)
-                .setMediaId(mediaId)
-                .setDataSourceDesc(DATA_SOURCE_DESC)
-                .setMetadata(new MediaMetadata2.Builder(context)
-                                .putString(MediaMetadata2.METADATA_KEY_MEDIA_ID, mediaId)
-                                .build())
-                .build();
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MockMediaSessionService2.java b/packages/MediaComponents/test/src/android/media/MockMediaSessionService2.java
deleted file mode 100644
index 64b1acd..0000000
--- a/packages/MediaComponents/test/src/android/media/MockMediaSessionService2.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static junit.framework.Assert.fail;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.SessionCallback;
-import android.media.TestServiceRegistry.SessionCallbackProxy;
-import android.media.TestUtils.SyncHandler;
-import android.support.annotation.NonNull;
-
-import java.util.concurrent.Executor;
-
-/**
- * Mock implementation of {@link android.media.MediaSessionService2} for testing.
- */
-public class MockMediaSessionService2 extends MediaSessionService2 {
-    // Keep in sync with the AndroidManifest.xml
-    public static final String ID = "TestSession";
-
-    private static final String DEFAULT_MEDIA_NOTIFICATION_CHANNEL_ID = "media_session_service";
-    private static final int DEFAULT_MEDIA_NOTIFICATION_ID = 1001;
-
-    private NotificationChannel mDefaultNotificationChannel;
-    private MediaSession2 mSession;
-    private NotificationManager mNotificationManager;
-
-    @Override
-    public void onCreate() {
-        TestServiceRegistry.getInstance().setServiceInstance(this);
-        super.onCreate();
-        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-    }
-
-    @Override
-    public MediaSession2 onCreateSession(String sessionId) {
-        final MockPlayer player = new MockPlayer(1);
-        final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler();
-        final Executor executor = (runnable) -> handler.post(runnable);
-        SessionCallbackProxy sessionCallbackProxy = TestServiceRegistry.getInstance()
-                .getSessionCallbackProxy();
-        if (sessionCallbackProxy == null) {
-            // Ensures non-null
-            sessionCallbackProxy = new SessionCallbackProxy(this) {};
-        }
-        TestSessionServiceCallback callback =
-                new TestSessionServiceCallback(sessionCallbackProxy);
-        mSession = new MediaSession2.Builder(this)
-                .setPlayer(player)
-                .setSessionCallback(executor, callback)
-                .setId(sessionId).build();
-        return mSession;
-    }
-
-    @Override
-    public void onDestroy() {
-        TestServiceRegistry.getInstance().cleanUp();
-        super.onDestroy();
-    }
-
-    @Override
-    public MediaNotification onUpdateNotification() {
-        if (mDefaultNotificationChannel == null) {
-            mDefaultNotificationChannel = new NotificationChannel(
-                    DEFAULT_MEDIA_NOTIFICATION_CHANNEL_ID,
-                    DEFAULT_MEDIA_NOTIFICATION_CHANNEL_ID,
-                    NotificationManager.IMPORTANCE_DEFAULT);
-            mNotificationManager.createNotificationChannel(mDefaultNotificationChannel);
-        }
-        Notification notification = new Notification.Builder(
-                this, DEFAULT_MEDIA_NOTIFICATION_CHANNEL_ID)
-                .setContentTitle(getPackageName())
-                .setContentText("Dummt test notification")
-                .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
-        return new MediaNotification(this, DEFAULT_MEDIA_NOTIFICATION_ID, notification);
-    }
-
-    private class TestSessionServiceCallback extends SessionCallback {
-        private final SessionCallbackProxy mCallbackProxy;
-
-        public TestSessionServiceCallback(SessionCallbackProxy callbackProxy) {
-            super(MockMediaSessionService2.this);
-            mCallbackProxy = callbackProxy;
-        }
-
-        @Override
-        public CommandGroup onConnect(@NonNull MediaSession2 session,
-                @NonNull ControllerInfo controller) {
-            return mCallbackProxy.onConnect(session, controller);
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/MockPlayer.java b/packages/MediaComponents/test/src/android/media/MockPlayer.java
deleted file mode 100644
index 05962cf..0000000
--- a/packages/MediaComponents/test/src/android/media/MockPlayer.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.media.MediaSession2.PlaylistParams;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.ArrayMap;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-
-/**
- * A mock implementation of {@link MediaPlayerBase} for testing.
- */
-public class MockPlayer extends MediaPlayerBase {
-    public final CountDownLatch mCountDownLatch;
-
-    public boolean mPlayCalled;
-    public boolean mPauseCalled;
-    public boolean mStopCalled;
-    public boolean mSkipToPreviousCalled;
-    public boolean mSkipToNextCalled;
-    public boolean mPrepareCalled;
-    public boolean mFastForwardCalled;
-    public boolean mRewindCalled;
-    public boolean mSeekToCalled;
-    public long mSeekPosition;
-    public boolean mSetCurrentPlaylistItemCalled;
-    public MediaItem2 mCurrentItem;
-    public boolean mSetPlaylistCalled;
-    public boolean mSetPlaylistParamsCalled;
-
-    public ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>();
-    public List<MediaItem2> mPlaylist;
-    public PlaylistParams mPlaylistParams;
-
-    private PlaybackState2 mLastPlaybackState;
-    private AudioAttributes mAudioAttributes;
-
-    public MockPlayer(int count) {
-        mCountDownLatch = (count > 0) ? new CountDownLatch(count) : null;
-    }
-
-    @Override
-    public void close() {
-        // no-op
-    }
-
-    @Override
-    public void reset() {
-        // no-op
-    }
-
-    @Override
-    public void play() {
-        mPlayCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    @Override
-    public void pause() {
-        mPauseCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void stop() {
-        mStopCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void skipToPrevious() {
-        mSkipToPreviousCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    @Override
-    public void skipToNext() {
-        mSkipToNextCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    @Override
-    public void prepare() {
-        mPrepareCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void fastForward() {
-        mFastForwardCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void rewind() {
-        mRewindCalled = true;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    @Override
-    public void seekTo(long pos) {
-        mSeekToCalled = true;
-        mSeekPosition = pos;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void setCurrentPlaylistItem(MediaItem2 item) {
-        mSetCurrentPlaylistItemCalled = true;
-        mCurrentItem = item;
-        if (mCountDownLatch != null) {
-            mCountDownLatch.countDown();
-        }
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Nullable
-    @Override
-    public PlaybackState2 getPlaybackState() {
-        return mLastPlaybackState;
-    }
-    */
-
-    @Override
-    public int getPlayerState() {
-        return mLastPlaybackState.getState();
-    }
-
-    @Override
-    public int getBufferingState() {
-        // TODO: implement this
-        return -1;
-    }
-
-    @Override
-    public void registerPlayerEventCallback(@NonNull Executor executor,
-            @NonNull PlayerEventCallback callback) {
-        mCallbacks.put(callback, executor);
-    }
-
-    @Override
-    public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback callback) {
-        mCallbacks.remove(callback);
-    }
-
-    public void notifyPlaybackState(final PlaybackState2 state) {
-        mLastPlaybackState = state;
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            final PlayerEventCallback callback = mCallbacks.keyAt(i);
-            final Executor executor = mCallbacks.valueAt(i);
-            // TODO: Uncomment or remove
-            //executor.execute(() -> callback.onPlaybackStateChanged(state));
-        }
-    }
-
-    public void notifyError(int what) {
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            final PlayerEventCallback callback = mCallbacks.keyAt(i);
-            final Executor executor = mCallbacks.valueAt(i);
-            // TODO: Uncomment or remove
-            //executor.execute(() -> callback.onError(null, what, 0));
-        }
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void setPlaylistParams(PlaylistParams params) {
-        mSetPlaylistParamsCalled = true;
-        mPlaylistParams = params;
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void addPlaylistItem(int index, MediaItem2 item) {
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void removePlaylistItem(MediaItem2 item) {
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public PlaylistParams getPlaylistParams() {
-        return mPlaylistParams;
-    }
-    */
-
-    @Override
-    public void setAudioAttributes(AudioAttributes attributes) {
-        mAudioAttributes = attributes;
-    }
-
-    @Override
-    public AudioAttributes getAudioAttributes() {
-        return mAudioAttributes;
-    }
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public void setPlaylist(List<MediaItem2> playlist) {
-        mSetPlaylistCalled = true;
-        mPlaylist = playlist;
-    }
-    */
-
-    // TODO: Uncomment or remove
-    /*
-    @Override
-    public List<MediaItem2> getPlaylist() {
-        return mPlaylist;
-    }
-    */
-
-    @Override
-    public void setDataSource(@NonNull DataSourceDesc dsd) {
-        // TODO: Implement this
-    }
-
-    @Override
-    public void setNextDataSource(@NonNull DataSourceDesc dsd) {
-        // TODO: Implement this
-    }
-
-    @Override
-    public void setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
-        // TODO: Implement this
-    }
-
-    @Override
-    public DataSourceDesc getCurrentDataSource() {
-        // TODO: Implement this
-        return null;
-    }
-
-    @Override
-    public void loopCurrent(boolean loop) {
-        // TODO: implement this
-    }
-
-    @Override
-    public void setPlaybackSpeed(float speed) {
-        // TODO: implement this
-    }
-
-    @Override
-    public void setPlayerVolume(float volume) {
-        // TODO: implement this
-    }
-
-    @Override
-    public float getPlayerVolume() {
-        // TODO: implement this
-        return -1;
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/SessionToken2Test.java b/packages/MediaComponents/test/src/android/media/SessionToken2Test.java
deleted file mode 100644
index efde78a..0000000
--- a/packages/MediaComponents/test/src/android/media/SessionToken2Test.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.content.Context;
-import android.os.Process;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.test.InstrumentationRegistry;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests {@link SessionToken2}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SessionToken2Test {
-    private Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @Test
-    public void testConstructor_sessionService() {
-        SessionToken2 token = new SessionToken2(mContext, mContext.getPackageName(),
-                MockMediaSessionService2.class.getCanonicalName());
-        assertEquals(MockMediaSessionService2.ID, token.getId());
-        assertEquals(mContext.getPackageName(), token.getPackageName());
-        assertEquals(Process.myUid(), token.getUid());
-        assertEquals(SessionToken2.TYPE_SESSION_SERVICE, token.getType());
-    }
-
-    @Test
-    public void testConstructor_libraryService() {
-        SessionToken2 token = new SessionToken2(mContext, mContext.getPackageName(),
-                MockMediaLibraryService2.class.getCanonicalName());
-        assertEquals(MockMediaLibraryService2.ID, token.getId());
-        assertEquals(mContext.getPackageName(), token.getPackageName());
-        assertEquals(Process.myUid(), token.getUid());
-        assertEquals(SessionToken2.TYPE_LIBRARY_SERVICE, token.getType());
-    }
-}
\ No newline at end of file
diff --git a/packages/MediaComponents/test/src/android/media/TestServiceRegistry.java b/packages/MediaComponents/test/src/android/media/TestServiceRegistry.java
deleted file mode 100644
index 27b6f89..0000000
--- a/packages/MediaComponents/test/src/android/media/TestServiceRegistry.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.media.MediaLibraryService2.MediaLibrarySession;
-import android.media.MediaSession2.CommandGroup;
-import android.media.MediaSession2.ControllerInfo;
-import android.media.TestUtils.SyncHandler;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Process;
-import android.support.annotation.GuardedBy;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-/**
- * Keeps the instance of currently running {@link MockMediaSessionService2}. And also provides
- * a way to control them in one place.
- * <p>
- * It only support only one service at a time.
- */
-public class TestServiceRegistry {
-    /**
-     * Proxy for both {@link MediaSession2.SessionCallback} and
-     * {@link MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback}.
-     */
-    public static abstract class SessionCallbackProxy {
-        private final Context mContext;
-
-        /**
-         * Constructor
-         */
-        public SessionCallbackProxy(Context context) {
-            mContext = context;
-        }
-
-        public final Context getContext() {
-            return mContext;
-        }
-
-        /**
-         * @param controller
-         * @return
-         */
-        public CommandGroup onConnect(@NonNull MediaSession2 session,
-                @NonNull ControllerInfo controller) {
-            if (Process.myUid() == controller.getUid()) {
-                CommandGroup commands = new CommandGroup(mContext);
-                commands.addAllPredefinedCommands();
-                return commands;
-            }
-            return null;
-        }
-
-        /**
-         * Called when enclosing service is created.
-         */
-        public void onServiceCreated(MediaSessionService2 service) { }
-
-        /**
-         * Called when enclosing service is destroyed.
-         */
-        public void onServiceDestroyed() { }
-
-        public void onSubscribe(@NonNull MediaLibrarySession session, @NonNull ControllerInfo info,
-                @NonNull String parentId, @Nullable Bundle extra) { }
-        public void onUnsubscribe(@NonNull MediaLibrarySession session,
-                @NonNull ControllerInfo info, @NonNull String parentId) { }
-    }
-
-    @GuardedBy("TestServiceRegistry.class")
-    private static TestServiceRegistry sInstance;
-    @GuardedBy("TestServiceRegistry.class")
-    private MediaSessionService2 mService;
-    @GuardedBy("TestServiceRegistry.class")
-    private SyncHandler mHandler;
-    @GuardedBy("TestServiceRegistry.class")
-    private SessionCallbackProxy mCallbackProxy;
-
-    public static TestServiceRegistry getInstance() {
-        synchronized (TestServiceRegistry.class) {
-            if (sInstance == null) {
-                sInstance = new TestServiceRegistry();
-            }
-            return sInstance;
-        }
-    }
-
-    public void setHandler(Handler handler) {
-        synchronized (TestServiceRegistry.class) {
-            mHandler = new SyncHandler(handler.getLooper());
-        }
-    }
-
-    public Handler getHandler() {
-        synchronized (TestServiceRegistry.class) {
-            return mHandler;
-        }
-    }
-
-    public void setSessionCallbackProxy(SessionCallbackProxy callbackProxy) {
-        synchronized (TestServiceRegistry.class) {
-            mCallbackProxy = callbackProxy;
-        }
-    }
-
-    public SessionCallbackProxy getSessionCallbackProxy() {
-        synchronized (TestServiceRegistry.class) {
-            return mCallbackProxy;
-        }
-    }
-
-    public void setServiceInstance(MediaSessionService2 service) {
-        synchronized (TestServiceRegistry.class) {
-            if (mService != null) {
-                fail("Previous service instance is still running. Clean up manually to ensure"
-                        + " previoulsy running service doesn't break current test");
-            }
-            mService = service;
-            if (mCallbackProxy != null) {
-                mCallbackProxy.onServiceCreated(service);
-            }
-        }
-    }
-
-    public MediaSessionService2 getServiceInstance() {
-        synchronized (TestServiceRegistry.class) {
-            return mService;
-        }
-    }
-
-    public void cleanUp() {
-        synchronized (TestServiceRegistry.class) {
-            final SessionCallbackProxy callbackProxy = mCallbackProxy;
-            if (mService != null) {
-                mService.getSession().close();
-                // stopSelf() would not kill service while the binder connection established by
-                // bindService() exists, and close() above will do the job instead.
-                // So stopSelf() isn't really needed, but just for sure.
-                mService.stopSelf();
-                mService = null;
-            }
-            if (mHandler != null) {
-                mHandler.removeCallbacksAndMessages(null);
-            }
-            mCallbackProxy = null;
-
-            if (callbackProxy != null) {
-                callbackProxy.onServiceDestroyed();
-            }
-        }
-    }
-}
diff --git a/packages/MediaComponents/test/src/android/media/TestUtils.java b/packages/MediaComponents/test/src/android/media/TestUtils.java
deleted file mode 100644
index 12b24c0..0000000
--- a/packages/MediaComponents/test/src/android/media/TestUtils.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.content.Context;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.session.MediaSessionManager;
-import android.media.session.PlaybackState;
-import android.os.Bundle;
-import android.os.Handler;
-
-import android.os.Looper;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-/**
- * Utilities for tests.
- */
-public final class TestUtils {
-    private static final int WAIT_TIME_MS = 1000;
-    private static final int WAIT_SERVICE_TIME_MS = 5000;
-
-    /**
-     * Finds the session with id in this test package.
-     *
-     * @param context
-     * @param id
-     * @return
-     */
-    // TODO(jaewan): Currently not working.
-    public static SessionToken2 getServiceToken(Context context, String id) {
-        MediaSessionManager manager =
-                (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
-        List<SessionToken2> tokens = manager.getSessionServiceTokens();
-        for (int i = 0; i < tokens.size(); i++) {
-            SessionToken2 token = tokens.get(i);
-            if (context.getPackageName().equals(token.getPackageName())
-                    && id.equals(token.getId())) {
-                return token;
-            }
-        }
-        fail("Failed to find service");
-        return null;
-    }
-
-    /**
-     * Compares contents of two bundles.
-     *
-     * @param a a bundle
-     * @param b another bundle
-     * @return {@code true} if two bundles are the same. {@code false} otherwise. This may be
-     *     incorrect if any bundle contains a bundle.
-     */
-    public static boolean equals(Bundle a, Bundle b) {
-        if (a == b) {
-            return true;
-        }
-        if (a == null || b == null) {
-            return false;
-        }
-        if (!a.keySet().containsAll(b.keySet())
-                || !b.keySet().containsAll(a.keySet())) {
-            return false;
-        }
-        for (String key : a.keySet()) {
-            if (!Objects.equals(a.get(key), b.get(key))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public static void ensurePlaylistParamsModeEquals(PlaylistParams a, PlaylistParams b) {
-        assertEquals(a.getRepeatMode(), b.getRepeatMode());
-        assertEquals(a.getShuffleMode(), b.getShuffleMode());
-    }
-
-    /**
-     * Handler that always waits until the Runnable finishes.
-     */
-    public static class SyncHandler extends Handler {
-        public SyncHandler(Looper looper) {
-            super(looper);
-        }
-
-        public void postAndSync(Runnable runnable) throws InterruptedException {
-            final CountDownLatch latch = new CountDownLatch(1);
-            if (getLooper() == Looper.myLooper()) {
-                runnable.run();
-            } else {
-                post(()->{
-                    runnable.run();
-                    latch.countDown();
-                });
-                assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
-            }
-        }
-    }
-}
